自己动手写俄罗斯方块(二)
来源:互联网 发布:python idle3.5.2 编辑:程序博客网 时间:2024/04/28 00:15
补:写的这些程序没运行,写之后就直接弄上来了,后来用这些程序来合成时,发现有些小错误,如有汉字字符,或名字写错,Rectangle函数的参数用错等。这里就不再改了,太过于麻烦,那些错误大家一眼就看看出来的。在合成版本中,所有错误均为被纠正过来J。
二 各部分的实现
1设定方块的大小及游戏区坐标
对此我们可以这样写:
- const int SquareSize = 20;
- const int GameSizeX = 50;
- const int GameSizeY = 50;
这样我们定义了方块各边的大小为20。游戏区开始坐标为(50,50);
这里的数组并不唯一,根据个人爱好而定。
我们这里我们还是有必要定义一下游戏区的信息:
- const int GameRegionWidth = 10;
- const int GameRegionHeight = 20;
- int GameMapStates[20][10];
//这里我曾试过分别使用GameRegionWidth 和GameRegionHeight代//替10 和 20,但我使用的编译器不支持。
2 建立游戏区:
建立游戏去,即一个20行,10列的网格游戏去,当然这个网格是隐藏的,是不显示出来的。也不需要我们区画的。只要我们心中有这个网格就OK。J
好,我们现在开始画了。我们使用的函数为.
- BOOL Rectangle(
- HDC hdc,
- int nLeftRect,
- int nTopRect,
- int nRightRect,
- int nBottomRect
- );
我们既然决定要使用这个函数我们就的得到该函数相应的参数。
- int LeftX = GameSizeX; //游戏区左上角横坐标
- int LeftY = GameSzieY; //游戏区坐上角纵坐标
- //游戏区右下角横坐标
- int RightX = GameSizeX + GameRegionWidth * SquareSize;
- //游戏区右下角纵坐标
- int RightY = GameSizeY + GameRegionHeight * SquareSize;
好的,我们已经得到5个参数中的四个参数了。至于HDC,我们可以根据当时的情况来获得。我们该函数不同的用处获得HDC的方式不同。好了,画游戏区的功能已经实现了,但我们总不能每次调用的时候都写这么多吧?我想为了美观与程序的易读性我们还是用个函数封装下好J。
好的,我们来封装一下该函数:
- void DrawGameRegion(HDC hdc)
- {
- int LeftX = GameSizeX; //游戏区左上角横坐标
- int LeftY = GameSzieY; //游戏区坐上角纵坐标
- //游戏区右下角横坐标
- int RightX = GameSizeX + GameRegionWidth * SquareSize;
- //游戏区右下角纵坐标
- int RightY = GameSizeY + GameRegionHeight * SquareSize;
- Rectangle(hdc,LeftX,LeftY,RightX,RightY);
- }
封装成功!
3 初始化俄罗斯方块的7中图形
- const POINT Terics[7][4][4] =
- {
- {
- 0,0,1,0,0,1,-1,1,
- 0,0,0,1,1,1,1,2,
- 0,0,1,0,0,1,-1,1,
- 0,0,0,1,1,1,1,2
- },
- {
- 0,0,1,0,1,1,2,1,
- 0,0,0,1,-1,1,-1,2,
- 0,0,1,0,1,1,2,1,
- 0,0,0,1,-1,1,-1,2
- },
- {
- 0,0,0,1,0,2,1,2,
- 0,0,0,1,-1,1,-2,1,
- 0,0,1,0,1,1,1,2,
- 0,0,0,1,1,0,2,0
- },
- {
- 0,0,0,1,0,2,-1,2,
- 0,0,1,0,2,0,2,1,
- 0,0,1,0,0,1,0,2,
- 0,0,0,1,1,1,2,1
- },
- {
- 0,0,0,1,0,2,0,3,
- 0,0,1,0,2,0,3,0,
- 0,0,0,1,0,2,0,3,
- 0,0,1,0,2,0,3,0
- },
- {
- 0,0,1,0,0,1,1,1,
- 0,0,1,0,0,1,1,1,
- 0,0,1,0,0,1,1,1,
- 0,0,1,0,0,1,1,1
- },
- {
- 0,0,1,0,2,0,1,1,
- 0,0,0,1,0,2,1,1,
- 0,0,0,1,-1,1,1,1,
- 0,0,0,1,0,2,-1,1
- }
- };
这个我也曾下到我的思路里了。为了完美只好在这里再写一遍了J。
哇,一大推的数字是什么意思啊?:-D,看似很难,其实很简单的。你
只需当前图形的形状和方向判断组成它的每个方块的右上角坐标比
当前坐标便宜多少,然后添上去就OK了。注意这里的坐标是游戏区
的坐标。即,偏移1相当于原来的坐标偏移一个方块边长的大小。
4 画方块
说了半天如何画一个方块还没实现呢,J这里我们仍然是函数封装。
- void DrawRectangle(HDC hdc,int x,int y)
- {
- int LeftX = GameSizeX + x * SquareSize;
- int LeftY = GameSizeY + y * SquareSize;
- int RightX = GameSizeX + SquareSize;
- int RightY = GameSizeY + SquareSize;
- Rectangle(hdc,LeftX,LeftY,RightX,RightY);
- }
5 画俄罗斯方块
方块画好了,我们该画各种形状的俄罗斯方块了。。仍然是函数封装哦J。
- void DrawTetromino(HDC hdc,int shape,int dir,int x,int y)
- {
- int index,nx,ny;
- for ( index = 0; index < 4; ++index)
- {
- nx = Terics[shape][dir][index].x + x;
- ny = Terics[shape][dir][index].y + y;
- DrawRectangle(hdc,nx,ny);
- }
- }
6判断范围
该画的我们都画好了,在让他移动之前我们先将它的范围设定一下吧。别急哦J
- BOOL IsOutOfRegion(int shape, int dir, int x, int y)
- {
- int index;
- int nx,ny;
- for (index = 0; index < 4; ++index)
- {
- nx = Terics[shape][dir][index].x + x;
- ny = Terics[shape][dir][index].y + y;
- if (ny < 0 || ny >= GameRegionHeight || nx < 0 || nx >= GameRegionWidth || GameMapStates[nx][ny] != 0)
- {
- return TRUE;
- }
- }
- return FALSE;
- }
7保存游戏区当前的状态
该是保存状态的时候了。。J这应该是写俄罗斯方块里最难得东西了(个人认为哈)。并不是这里的代码有多难,而是它的思想难。
- void SaveStateofTerics(int shape, int dir, int x, int y)
- {
- int index;
- int nx,ny;
- for ( index = 0; index < 4; ++index)
- {
- nx = Terics[shape][dir][i].x + x;
- nx = Terics[shape][dir][i].y + y;
- GameMapStates[nx][ny] = 1;
- }
- }
8 消去一行
- void DeleteTericsFromOfGameRegion(int shape, int dir, int x, int y)
- {
- bool flag = TRUE;
- int indexX,indexY;
- int m,n;
- for (indexX = 0; indexX < GameRegionHeight; ++index)
- for (indexY = 0; indexY < GameRegionWidth; ++indexY)
- {
- if (GameMapStates[indexX][indexY] != 1)
- {
- flag = FALSE;
- }
- if (flag)
- {
- for (m = indexX; m >= 0; --m)
- for (n = 0; n < GameRegionWidth;++n)
- {
- GameMapStates[m][n] = GameMapStates[m-1][n]
- }
- }
- }
9显示问题
对于显示问题,我们使用我们的思路里的第二种方法来实现,故我们需要定义擦除函数,加载函数。好的,我们开始吧。J
- void EraseGameRegion(HDC hdc)
- {
- RECT rect;
- rect.left = GameSizeX;
- rect.top = GameSizeY;
- rect.right = GameSizeX + GameRegionWidth * SquareSize;
- rect.bottom = GameSizeY + GameRegionHeight * SquareSize;
- HBRUSH brush = CreateSolidBrush(RGB(255,255,255));
- FillRect(hdc,&rect,brush);
- DrawGameRegion(hdc);//游戏区被删除,重新画一边
- }
定义加载函数
- void LoadCurrentTerics(HDC hdc)
- {
- int indexX,indexY;
- for (indexX = 0; indexX < GameRegionWidth; ++indexX)
- for (indexY = 0; indexY < GameRegionHeight; ++indexY)
- {
- if (GameMapStates[indexX][indexY] == 1)
- {
- DrawRectangle(hdc,indexX,indexY);
- }
- }
- }
10 初始化问题
在俄罗斯方块游戏中因为每次新方块都是从固定的地方出来,所以我们应该对之有一个初始化。为此我们还应该定义一个变量来保存当前图形的形状,方向,坐标;
- struct CurrentTerics{
- int shape,dir,x,y;
- }CurrentTericInfo;
注意这个应该为一个全局的。
封装一个初始化函数:
- void InitTericsInfo()
- {
- srand((unsigned)time(NULL));
- CurrentTericsInfo.shape = rand()%7;
- CurrentTericsInfo.dir = 0;
- CurrentTericsInfo.x = 4;
- CurrentTericsInfo.y = 0;
- }
好的。至此一个俄罗斯方块的各部分都已实现,只剩下组装工作了。至于如何组装,该把这些函数放到那里,我的理路里都已有了大部分的方法。
参照帖子:http://www.rupeng.com/forum/thread-2533-1-1-uid2704.html
http://www.rupeng.com/forum/thread-3195-1-1-uid2704.html
- 自己动手写俄罗斯方块(二)
- 自己动手写俄罗斯方块(二)
- 自己动手写俄罗斯方块(一)
- 自己动手写俄罗斯方块(三)
- 自己动手写俄罗斯方块(一)
- 自己动手写俄罗斯方块(三)
- shell写俄罗斯方块二
- 自己动手写操作系统(二)
- 自己动手写操作系统(二)
- 自己动手写操作系统(二)
- 自己动手写操作系统(二)
- 俄罗斯方块 - 自己动手小游戏
- 自己动手写操作系统(二) 作者:伊梅
- 自己动手写操作系统(二) 作者:伊梅
- 自己动手写basic解释器(二)
- 自己动手写一个APK安装器(二)
- 自己动手写word2vec (二):统计词频
- <自己动手写cpu>之二总结
- 谁有VS T人外挂地址说下
- 随机数
- mssql 列内数据横向连接,用逗号分割。
- 自己动手写俄罗斯方块(一)
- Linux 常见文件类型--02/07/10
- 自己动手写俄罗斯方块(二)
- 自己动手写俄罗斯方块(三)
- sizeof总结
- 朝花夕拾
- 表达式求值思路总结
- (ZJU-2008复试)-HDOJ-1880-魔咒词典
- strcmp、fseek和ftell函数
- 从编译ipmsg开始
- 深入解析enum