C++俄罗斯方块
来源:互联网 发布:java log4j maven 编辑:程序博客网 时间:2024/05/20 16:41
前言
一个礼拜前想做一个俄罗斯方块小游戏,因为想用c++实现,但又受制于界面,于是苦读了几天的Qt。昨天开工连带一个不眠夜,总算是大功告成,个中滋味,怕是只有自己知道。
简介
俄罗斯方块,c++,qt。
功能:常规俄罗斯方块具有的:方块旋转,左移,右移,下落加速,消行,提示下一块样式等等都已实现。同时实现了记分以及暂停的功能。
效果图
游戏过程效果图
暂停效果图
游戏结束效果图
实现思路
提到俄罗斯方块,稍微麻烦一些的地方只有三点
1. 方块旋转
#1###1###11###########1#111##########11###1###1######111#1######
上面四个小矩阵我们很容易看出,它是L型图案的四种不同形态,用4*4的矩阵来将它们统一表示,再细心一点的小伙伴还会发现,它们的顺序也是按照逆时针旋转进行排列的。
那么加入我们对上面四个小矩阵进行编号为1,2,3,4。
那么显然1-旋转-> 2 -旋转-> 3 -旋转-> 4 -旋转->1
如果我们开辟一NEXT数组用来保存方块对应的旋转后的方块编号。
则NEXT[1] = 2; NEXT[2] = 3; NEXT[3] = 4; NEXT[4] = 1;
举一反三,别的形状方块也是一样的。
2. 碰撞检测
上文,我们用一个四维小矩阵来表示方块,我们可以对它规定一个重心,索性就用左上角(0, 0)点来作为重心吧。
这个重心只是用来与实际地图相对应的一个相对点而已。
我们以将小矩阵忽略,只在意重心那个点,通过重心点所在地图的坐标,显然可以求出其他点位于地图的坐标。
这样一来,每次操作方块时,将方块将要变换到的位置与地图进行比较,通过简单的判断,可以得出是否有重复部分,若重复,则可以移动,否则不可以。
3. 方块自动下降
这个是最容易解决的,qt里有个QTimer类,有定时功能,设定一定时间间隔,触发timerEvent事件。在事件里,做你想做的即可。
代码构成
全部代码仅实现三个类
1. Board 游戏地图信息
class Board{public: int score;//当前分数 int maxScore;//最高分 int time;//每次下落的间隔时间 int width;//地图宽 int height;//地图高 Block *block;//下落的方块 char map[100][100];//保存地图信息 Board(int, int); void confirm();//将下落到底的块更新到map bool isEnd();//判断是否游戏结束};
2. Block 方块信息及操作
class Block{public: char BLOCKS[20][5][5];//各个类型的方块 int NEXT[20];//模拟指向用于方块旋转 Qt::GlobalColor COLOR[20];//各个类型方块的颜色 int x;//块重心起始坐标 int y; int type;//块id int nextType;//下一个块id Board *board; Block(Board *);//构造函数 void toNext();//更改块id void moveUp();//变形 void moveRight();//加速 void moveLeft();//左移 void moveDown();//右移 bool detect(int);//碰撞检测};
3. mainWindow 游戏界面部分
class MainWindow : public QMainWindow{ Q_OBJECTpublic: bool flag;//判断是否暂停状态 QTimer *timer;//定时器 Board *board;//游戏所用地图类 MainWindow(Board *, QWidget *parent = 0); void paintEvent(QPaintEvent *event);//绘制界面 void keyPressEvent(QKeyEvent *);//键盘事件处理signals:public slots: void timerEvent();//定时事件private:};
核心代码
粗略估计了下,代码总量约500行,所以这里就只贴自己认为核心的部分,完整项目文件及可执行程序会上传到git上,下面会给出链接。有兴趣的朋友去down一下即可。
碰撞检测
bool Block::detect(int flag){ //获得当前操作的目标状态:目标坐标,目标方块类型。 int nextX, nextY, nextType; // 0,1,2,3对应上下左右 switch(flag) { case 0: nextX = x; nextY = y; nextType = NEXT[type]; break; case 1: nextX = x+1; nextY = y; nextType = type; break; case 2: nextX = x; nextY = y-1; nextType = type; break; case 3: nextX = x; nextY = y+1; nextType = type; break; } for(int i=0; i<4; i++) for(int j=0; j<4; j++) { //tx,ty表示i,j所对应的地图的实际位置。 int tx = nextX+i; int ty = nextY+j; //边界处理 if(tx < 0 || tx > board->height+1 || ty < 0 || ty > board->width+1) continue; //如果块与地图墙相重合,则发生碰撞 if(BLOCKS[nextType][i][j] != '#' && (ty == 0 || ty == board->width+1)) return false; if(BLOCKS[nextType][i][j] != '#' && board->map[tx][ty] != '#') return false; } return true; }
方块沉底后的地图信息更新及消行记分操作
void Board::confirm(){ //将块更新到map for(int i=0; i<4; i++) for(int j=0; j<4; j++) { int tx = block->x + i; int ty = block->y + j; if(tx<1 || tx > height || ty < 1 || ty > width) continue; if(block->BLOCKS[block->type][i][j] != '#') map[tx][ty] = block->BLOCKS[block->type][i][j]; } //消去完整的行并计算行个数 int cnt = 0; for(int i=height; i>=1; i--) { bool flag = false; for(int j=1; j<=width; j++) if(map[i][j] == '#') { flag = true; break; } if(flag) continue; cnt++; for(int j=i; j>=1; j--) for(int k=1; k<=width; k++) map[j][k] = map[j-1][k]; } //每下落一个块加5分 score += 5; //根据同时消去的行的数量指数型记分 //1-10 2-20 3-40 4-80 if(cnt) score += 10*(1<<cnt); //实时更新最大值 maxScore = std::max(maxScore, score); //每下落一个块,时间间隔减2 time -= 2; if(time < 0) time = 0; //更新块 block->toNext();}
完整代码
我的github链接:
https://github.com/shiyi1996/game
哈哈,分享成果的过程总是令人快乐的。
最后,如果有道友发现其中有出错的地方,还望不吝指出。
若有更好的写法也可交流一二,大家一起进步嘛!
- 俄罗斯方块(C++)
- C-俄罗斯方块 TURBOC 2.0
- 俄罗斯方块(C#.net 2003)
- c语言俄罗斯方块编程
- 俄罗斯方块c源代码
- 俄罗斯方块(C语言版)
- 俄罗斯方块之C语言版
- C语言编写俄罗斯方块
- C实现的俄罗斯方块
- 俄罗斯方块c源代码
- C俄罗斯方块源代码
- C + API俄罗斯方块
- 俄罗斯方块源代码 C语言
- 俄罗斯方块(C语言版)
- 俄罗斯方块游戏C语言
- 俄罗斯方块游戏 (C++)
- C语言 俄罗斯方块
- 俄罗斯方块(C语言)
- C++ map
- 程序员的出路之一
- spring框架中多数据源创建加载并且实现动态切换的配置实例代码
- 数据结构与算法之反转链表
- Linux下常用文件操作命令总结
- C++俄罗斯方块
- [Java开发之路](25)引用类型
- 105. Construct Binary Tree from Preorder and Inorder Traversal
- Qt浅谈之四十九俄罗斯方块(代码来自网络)
- java文件io之PrintWriter
- C++ vector
- 第三方框架实现横向滚动条
- 我眼中的maven
- C/C++—— 对多态现象的理解