南昌大学|中正论坛

 找回密码
 注册[30秒完成]
搜索
查看: 7373|回复: 11
打印 上一主题 下一主题

[软件] 用C开发游戏经典案例------------俄罗斯方块

[复制链接]
跳转到指定楼层
1#
发表于 2006-7-11 13:00:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
明天中午接着写 ,现在该工作了
不好意思 ^o^
2#
 楼主| 发表于 2006-7-12 12:51:45 | 只看该作者

绪写

学习win32以后 我们总想用他写点东西,可惜的是我们能看懂这些win32程序,自己写的时候就麻木,不知道如何下手。
我现在要说的游戏编程是利用Cwin32和MFC相结合的产品。
首先我们基于MFC建立一个基于单文档的工程,其他选项不变,不过为了程序写完后我们能在朋友面前显示一下,最好把库连接方式改为静态设置
现在我们有了基本的框架了,本人觉得这个框架没必要去用win32去写

然后就简单了

首先建立个头文件
ComData.h
在这个文件里我们写一些经常用到的东西
首先是文档
#define  TITLE_MAIN    "俄罗斯方块游戏"
#define TITLE_ERROR "错误提示"  //这个主要用于消息提示

消息机制

#define MSG_GAMEOVER  "游戏结束"
#define MSG_OVERFILL    "超缓存" //用于测试内存泄漏

/;/定义小方块大小(像素)
#define CELL   15
//定义游戏屏幕的大小 (以格数为单位)
#define  SCR_WID     24
#define  SCR_HEI      12 //

//这样基本信息我们已经创建,以后如有需要的信息我们可以在这个头文件中添加

//用向导建立一个类,我这个类来管理所有的方块操作
class CTempBlock
{
     //构造函数以及西沟函数略
  private :
    //定义 移动的 小方块 4X4结构
  int  iExist[4][4];
    COLORREF clr;//移动方块的颜色
  public:
    void Create(); //用于创建小方块
  // 时间不够明天接着写 不好意思 中午就一个小时的时间 我还得吃饭
  // 以后给你们上传更好的代码!!
}

评分

1

查看全部评分

3#
发表于 2006-7-13 10:31:01 | 只看该作者
这么点算什么与什么啊?
4#
 楼主| 发表于 2006-7-14 13:01:13 | 只看该作者

接商会

class CTempBlock
{
     //构造函数以及西沟函数略
  private :
    //定义 移动的 小方块 4X4结构
  int  iExist[4][4];
    COLORREF clr;//移动方块的颜色
  CellType      cellType ;//定义方块的形式,这个数据结构我们在共通函数里面有定义
  //下面的2 个变量用于控制移动的小方块(1,1)的游戏区域中的位置,其他小方块的位置可以相对于改为只算出
  int Row_X;
    int Col_Y;
  public:
    void Create(); //用于创建小方块
  void Move(MoveModal mm); //MoveModal 是控制方块移动或旋转的数据结构,
                           //这个数据结构我们在共通函数里面有定义
  Init();//初始化函数
  void DrawCell(CDC *pDC);
} ;
现在我们已经有了在窗体中移动的小方块了
下面就是定义游戏区域
class GameState
{
private:
       int iExist[SCR_HEI][SCR_WID ];
       COLORREF clrArray[SCR_HEI][SCR_WID ];
public:
     void DrawState(CDC * pDC);//这里不能用HDC,因为我们在MFC里做程序,不用那么麻烦,传递CDC就可以
};
游戏区域创建完毕
这是我们就可以开始组装游戏了
首先得定义好游戏场景
背景色为 黑色  这个我们在共通头函书中有定义
小方块边线的颜色  这个我们在共通头函书中有定义
小方块的颜色种类  这个我们在共通头函书中有定义
设置背景色应该不用我说吧
pDC->FillRect(&rect,pBrush);
丛这个函数应该能看出来
变现的颜色在这里我们不用考虑,我们在上面的类中的DrawXXX汉书中就已经考虑到
下面就是如何控制
首先1:产生方块
假如我们在试图文件中定义了变量
CTempBlock  tempBlock;
tempBlock.Create();//有着个函数创建方块,具体代买以后在这,我们先弄清概念
// 明天接着写,又到1点了 时间真短
5#
发表于 2006-7-14 19:11:27 | 只看该作者
接着写吧 写完了我拿VB写下
6#
 楼主| 发表于 2006-7-17 13:00:05 | 只看该作者

接上会

我们首先创建了一个小方块
玩过俄罗斯方块的人多知道,我们还得有个通知下一个是什么方块!
我们再定义一个变量 CTempBlock  nextBlock
nextBlock.Create();
这是我们有了2个方块
然后就是让方块动起来
先创建一个时间事件,建议这里不用另开线程,为什么-----不解释
然后就是启动时间事件,同时要记住时间事件的句柄
UINT mTimer;
mTimer = this.SetTimer(1,1000);
参数的意义不解释,自己去查帮助文档
我们在时间事件里让方块动起来
tempBlock.Move(MM_DOWN);
现在方块在试图区域中可以自己向下移动了,但是我们还看不见!
我们在onpaint事件中写绘图函数
CDC*pDC;
pDC = GetDC();
tempBlock.Draw(pDC);
现在我们可以看见一个小方块在试图区域中自己向下移动,不过有点缺点,就是闪屏
如何解决闪屏 --------- 等所有东东完事后,我们再说
现在我们要做的就是如何判断移动的合法性??
什么时候可以向右移,左移,下移,变形??
思路:
我们在纪录移动小方块的位置是 自纪录 索引为 (1,1)的小方块,他的位置正好的游戏区域的索引
//明天接着写吧
7#
 楼主| 发表于 2006-7-18 12:48:57 | 只看该作者
我们在控制方块移动的时候,只需要知道他的下一个位置是否有小小方块,如果有则不能移动
我门定义的方块为4X4结构
//算法---左移
int  posX,posY;
for(int x = 0; x<5;x++)
  for(int y = 0;yx<5;y++)
{
    if(iExist[x][y] == 0)
          continue;
   GetPos(posX,posY,x,y);
   // 我们知道 方块的位置就是游戏区域的索引
// 所以
  if(gs.iExist[posX-1][posY] == 1)
         return false;
}
return true;
上面的算法,看是正确,但是有危险,posX-1很有可能小于0,而数组的索引不能小于0,也不可能大于等于定义值
所以在上面的算法中我们还要加格判断,否则程序在运行的时候会出错。
这样我们就可以知道 如何判断左移,下移,以及 变形的合法控制了

这些做完后我们就可以 完善游戏了

首先给程序添加个时间事件---------再XXXXView.h/.cpp中添加
再时间中我们写
if(tempBlock.Move(MM_DOWN) == false)
{
      Swap();
     tempBlock.Create();
}
//上面的只能是控制自动向下运动
//我们还要自己控制他
//给程序添加keyDown/up事件
添加如下代码
switch(nChar)
{
case VK_LFET:
    return;
case VK_RIGHT:
tempBlocl.Move(MM_RIGHT);
return;
case VK_DOWN:
tempBlocl.Move(MM_DOWN)
return;
case VK_UP:
tempBlocl.Move(MM_CHG);//变形
return;
}
//
8#
 楼主| 发表于 2006-7-20 12:51:02 | 只看该作者
上面的代码基本上代码基本上实现了所有功能
现在要做的就是 具体的实现?
如何产生移动的小方块?
利用数据把它写死就可以
一共7种类型的方块
Create()
{
         int i = rand()5000;
         i =  i % 7;
        switch(i)
       {
       case 0:
      case 1:
      case 2:
      ....
     //省略的代码应该不用我写出来了吧,很简单的
   // 有个问题,细心的人应该能发现,为什么要  rand()5000 再    i =  i % 7
   // 为什么不直接 rand()%7呢?我们想想 从 5000 个数里面 抽 一个数 和 从 7 个数里面  
  //抽一个数的几率那个大?其实5000 已经够了,如果想减小游戏难度 可以 用小点的数
       }
    还有个问题就是产生随机数的问题? 没期启动的时候 我们会发现初始的方块多一样?
只要加个函数 srand 就可以,怎么用??看帮助文档,代码放在什么地方在C里面放在InitXXX事件中就可以。
}
9#
 楼主| 发表于 2006-7-21 12:42:22 | 只看该作者

如何解决闪屏问题

我们在做完游戏后,会发现出现闪屏现象!怎么办??
我们可以使用2级缓存的感念来解决这个问题
首先我们在内存中创建一个绘图设备
CDC tempDC;
然后获得当前程序的绘图设备
CDC*pDC = GetDC();
//
创建当前设备的批陪设备
tempDC.CreateCompatibleDC(pDC);
这是我们就可以在tempDC上绘图了,否则无法再tempDC上绘图
然后就是创建画板
CBitmap bitmap,*oldBitmap;
bitmap.CreateCompatilbeBitmap(pDC,width,height);
再把位图选入设备tempDC
oldBitmap = tempDC.SelectObject(&bitmap);
这是我们就可以安全的在tempDC上绘图了
绘完图后,我们再把整个tempDC上的图片拷贝到pDC上就可以了
ok 闪屏文体 就解决了
10#
发表于 2006-8-5 18:57:32 | 只看该作者
支持了~加分!
11#
发表于 2006-8-6 20:28:57 | 只看该作者
LZ够寒,,,标题是c.....里面是MFC(c++).......
12#
 楼主| 发表于 2006-8-7 12:28:51 | 只看该作者

回帖

其实MFC是对win32封装,而且程序中也是用了win32 API函数

我想我没有必要把界面的程序用win32也给你写一遍吧

所以别和我计较win32或者mfc
您需要登录后才可以回帖 登录 | 注册[30秒完成]

本版积分规则

手机访问本页请
扫描左边二维码
         本网站声明
本网站所有内容为网友上传,若存在版权问题或是相关责任请联系站长!
站长联系QQ:7123767   myubbs.com
         站长微信:7123767
请扫描右边二维码
www.myubbs.com

小黑屋|手机版|Archiver|南昌大学论坛 ( 琼ICP备10001196号-2 )

GMT+8, 2024-4-26 17:36 , Processed in 0.123239 second(s), 19 queries .

Powered by 高考信息网 X3.3

© 2001-2013 大学排名

快速回复 返回顶部 返回列表