用C++和EasyX图形库编写一个简单的打砖块游戏(下)
2017-10-09 13:18
796 查看
大家好,我终于更新啦。昨天是国庆节最后一天,我也回到了学校,决定趁势把这篇文章更新完,结果也是花了一天多的时间才完成呢。
回顾上篇,我们已经完成了砖块类和木板类的定义,现在只缺少一个活蹦乱跳的小球,这个小游戏就算完成了。话不多说,我们现在马上开始。
对于一个小球的话,让我们先想想我们需要定义些什么,处理些什么。
首先是小球的尺寸和位置,这个容易,用r表示小球半径,ballx,bally代表小球坐标,用addx,addy描述小球在xOy坐标系上的运动方向。另外在初始化小球坐标时,可以将小球摆在木板的上表面的中心位置处;
其次要处理的问题,也是最核心的两个问题是,小球与砖块的碰撞、小球与木板的碰撞,具体计算的我们稍后讨论。
以上便是我们定义小球类的思路。首先我们给出小球类的部分。
类中定义的两个标志量,将会在接下来的成员函数中用到。
下面我用一张图解释小球与砖块的碰撞关系,理解了这以后,小球和木板的碰撞同理。
除此之外,还有小球碰到边界后反弹,这个倒也容易。
另外关于小球与木板或是砖块间的碰撞,大家可以多画图,多试验。下面的代码我自己确实摸索了很久,能有现在这个效果我也还是挺开心了。
具体代码如下。
至此,我们只需要在自定义函数Gaming中调用以上的类就行了。这其中我们还需要一些按钮选择,比如退出或是重试,使用函数MessageBox即可。下面贴出完整的源代码,同时我也会把源代码上传到百度网盘,地址我会留在文章结尾处的。
终于结束啦,我很高兴这次能与大家一起分享这个小游戏,最后谢谢大家了。
百度网盘 源码下载链接:http://pan.baidu.com/s/1gfIk6av 密码:obw4
回顾上篇,我们已经完成了砖块类和木板类的定义,现在只缺少一个活蹦乱跳的小球,这个小游戏就算完成了。话不多说,我们现在马上开始。
对于一个小球的话,让我们先想想我们需要定义些什么,处理些什么。
首先是小球的尺寸和位置,这个容易,用r表示小球半径,ballx,bally代表小球坐标,用addx,addy描述小球在xOy坐标系上的运动方向。另外在初始化小球坐标时,可以将小球摆在木板的上表面的中心位置处;
其次要处理的问题,也是最核心的两个问题是,小球与砖块的碰撞、小球与木板的碰撞,具体计算的我们稍后讨论。
以上便是我们定义小球类的思路。首先我们给出小球类的部分。
class Ball { public: const int r = 8; //定义球的半径 const int speed = 1; //定义球的飞行速度 int ballx, bally; //定义球的坐标 int addx, addy; //表示球的飞行方向 //设置两个个标志量 bool go; //小球是否发射 bool iscatch; //木板是否捕捉到了小球 //构造函数 使小球初始时位于木板中心上 参数是木板的宽 Ball(int board_wide) { ballx = WINDOW_WIDE / 2; bally = WINDOW_HEIGHT - board_wide - r - 1; //初始时小球向右上方发射 addx = 1; addy = -1; go = 0; //初始化状态 小球未发射出去 iscatch = 1; //初始化状态 球被木板接住 }; }
类中定义的两个标志量,将会在接下来的成员函数中用到。
下面我用一张图解释小球与砖块的碰撞关系,理解了这以后,小球和木板的碰撞同理。
除此之外,还有小球碰到边界后反弹,这个倒也容易。
另外关于小球与木板或是砖块间的碰撞,大家可以多画图,多试验。下面的代码我自己确实摸索了很久,能有现在这个效果我也还是挺开心了。
具体代码如下。
class Ball { public: const int r = 8; //定义球的半径 const int speed = 1; //定义球的飞行速度 int ballx, bally; //定义球的坐标 int addx, addy; //表示球的飞行方向 //设置两个个标志量 bool go; //小球是否发射 bool iscatch; //木板是否捕捉到了小球 //构造函数 使小球初始化时位于木板中心上 Ball(int board_wide) { ballx = WINDOW_WIDE / 2; bally = WINDOW_HEIGHT - board_wide - r - 1; //初始时小球向右上发射 addx = 1; addy = -1; go = 0; //初始化状态 小球未发射出去 iscatch = 1; //初始化状态 球被木板接住 }; //小球移动函数 void Move(Bricks &brick, Board &board) { BeginBatchDraw(); //开启批量画图模式 目的是消除闪烁 //处理边界:左,右,上边界要反弹 if (ballx >= WINDOW_WIDE - r || ballx <= r) { addx *= -1; } if (bally <= r) { addy *= -1; } //若小球触及下边界 说明木板板没有接住小球 退出 if (bally >= WINDOW_HEIGHT - r) { iscatch = 0; return; } //判断小球和木板的碰撞(小球发射出去后才能判断 即go = 1) if (go&&ballx + 1 >= board.x - r&&ballx - 1 <= board.x + board.length + r&&bally + 1 >= board.y - r) { go = 0; //小球未发射 if (bally + 1 <= board.y) //接住了 小球反向 addy *= -1; else if (bally < WINDOW_HEIGHT - r) //这里是对小球碰撞到木板左右侧面的情况进行处理 { addx *= -1; addy *= -1; } } int flag = 0; //表示未小球击中任一砖块 for (int i = 0; i < brick.y && !flag; i++) { for (int j = 0; j < brick.x && !flag; j++) { //此处有砖块 且小球在该砖块的碰撞范围内 if (brick.bricks[i][j] == 0 && ballx + 1 >= j*brick.length - r&&ballx - 1 <= (j + 1)*brick.length + r&&bally + 1 >= i*brick.wide - r&&bally - 1 <= (i + 1)*brick.wide + r) { //左右两边 if (bally + 1 > i*brick.wide - r&&bally - 1 < (i + 1)*brick.wide) addx *= -1; //上下两边(图中两灰色直线之间的部分) else if (ballx + 1 >= j*brick.length && ballx - 1 <= (j + 1)*brick.length) addy *= -1; //四个顶角处 else continue; brick.bricks[i][j] = 1; //此处砖块被打掉了 brick.count--; //砖块数减一 flag = 1; //击中了 不用继续遍历 setfillcolor(BLACK); //将击中的砖块用黑色覆盖掉 fillrectangle(j*brick.length, i*brick.wide, (j + 1)*brick.length, (i + 1)*brick.wide); } }// }//for setfillcolor(BLACK); //擦除小球当前位置 solidcircle(ballx, bally, r); ballx += addx*speed; //更新位置 bally += addy*speed; if (bally + 1 < board.y - r) go = 1; //小球成功发射 setfillcolor(RED); //在新位置画小球 solidcircle(ballx, bally, r); FlushBatchDraw(); //把之前所有的绘图内容显示出来,与BeginBatchDraw()对应 Sleep(3); //休眠,就是暂停,使小球慢慢地运动。修改参数的值,可以变相改变游戏速度 } };
至此,我们只需要在自定义函数Gaming中调用以上的类就行了。这其中我们还需要一些按钮选择,比如退出或是重试,使用函数MessageBox即可。下面贴出完整的源代码,同时我也会把源代码上传到百度网盘,地址我会留在文章结尾处的。
#include<graphics.h> #include<conio.h> const int WINDOW_HEIGHT = 600; //定义窗口的高 const int WINDOW_WIDE = 400; //定义窗口的宽 class Bricks { public: int bricks[12][12]; //用二维数组保存所有砖块 int count; //记录砖块总数 const int x = 10, y = 5; //确定砖块有几排(y)几列(x) const int length = WINDOW_WIDE / x; //计算每个砖块的长和宽 const int wide = 20; //构造函数 Bricks() { memset(bricks, 0, sizeof(bricks)); //初始化 0表示有砖块 count = x*y; //计算砖块总数 } //画出所有的砖块 void drawallbricks() { setfillcolor(YELLOW); //设置砖块颜色 setlinecolor(BLACK); //设置边框颜色 for (int i = 0; i < y; i++) for (int j = 0; j < x; j++) fillrectangle(j*length, i*wide, (j + 1)*length, (i + 1)*wide); } }; class Board //定义木板类 { public: int x, y; //定义板的坐标 const int length = 60; //定义板的长度 const int wide = 15; //定义板的宽度 //构造函数 将木板的坐标初始化在中心位置 Board() { x = WINDOW_WIDE / 2 - length / 2; y = WINDOW_HEIGHT - wide; } //木板移动函数 void Move() { int ch; //接受一个键值 ch = _getch(); setfillcolor(BLACK); //将木板当前位置用背景色黑色覆盖 solidrectangle(x, y, x + length, y + wide); switch (ch) { case 75: //每次左移木板长度的1/3 case 'A': case 'a': x -= length / 3; break; case 77: //每次右移木板长度的1/3 case 'D': case 'd': x += length / 3; break; } //木板左右移动的边界限制 if (x <= 0) x = 0; if (x >= WINDOW_WIDE - length) x = WINDOW_WIDE - length; setfillcolor(BLUE); //更新坐标后画新木板 solidrectangle(x, y, x + length, y + wide); } }; class Ball { public: const int r = 8; //定义球的半径 const int speed = 1; //定义球的飞行速度 int ballx, bally; //定义球的坐标 int addx, addy; //表示球的飞行方向 //设置两个个标志量 bool go; //小球是否发射 bool iscatch; //木板是否捕捉到了小球 //构造函数 使小球初始化时位于木板中心上 Ball(int board_wide) { ballx = WINDOW_WIDE / 2; bally = WINDOW_HEIGHT - board_wide - r - 1; //初始时小球向右上发射 addx = 1; addy = -1; go = 0; //初始化状态 小球未发射出去 iscatch = 1; //初始化状态 球被木板接住 }; //小球移动函数 void Move(Bricks &brick, Board &board) { BeginBatchDraw(); //开启批量画图模式 //处理边界:左,右,上边界要反弹 if (ballx >= WINDOW_WIDE - r || ballx <= r) { addx *= -1; } if (bally <= r) { addy *= -1; } //若小球触及下边界 说明木板板没有接住小球 if (bally >= WINDOW_HEIGHT - r) { iscatch = 0; return; } //判断小球和木板的碰撞(小球发射出去后才能判断 即go = 1) if (go&&ballx + 1 >= board.x - r&&ballx - 1 <= board.x + board.length + r&&bally + 1 >= board.y - r) { go = 0; //小球未发射 if (bally + 1 <= board.y) //接住了 小球反向 addy *= -1; else if (bally < WINDOW_HEIGHT - r) //这里是对小球碰撞到木板左右侧面的情况进行处理 { addx *= -1; addy *= -1; } } int flag = 0; //表示未小球击中任一砖块 for (int i = 0; i < brick.y && !flag; i++) { for (int j = 0; j < brick.x && !flag; j++) { //此处有砖块 且小球在该砖块的碰撞范围内 if (brick.bricks[i][j] == 0 && ballx + 1 >= j*brick.length - r&&ballx - 1 <= (j + 1)*brick.length + r&&bally + 1 >= i*brick.wide - r&&bally - 1 <= (i + 1)*brick.wide + r) { //左右两边 if (bally + 1 > i*brick.wide - r&&bally - 1 < (i + 1)*brick.wide) addx *= -1; //上下两边 else if (ballx + 1 >= j*brick.length && ballx - 1 <= (j + 1)*brick.length) addy *= -1; //四个顶角处 else continue; brick.bricks[i][j] = 1; //此处砖块被打掉了 brick.count--; //砖块数减一 flag = 1; //击中了 不用继续遍历 setfillcolor(BLACK); //将击中的砖块用黑色覆盖掉 fillrectangle(j*brick.length, i*brick.wide, (j + 1)*brick.length, (i + 1)*brick.wide); } }// }//for setfillcolor(BLACK); //擦除小球当前位置 solidcircle(ballx, bally, r); ballx += addx*speed; //更新位置 bally += addy*speed; if (bally + 1 < board.y - r) go = 1; //小球成功发射 setfillcolor(RED); //在新位置画小球 solidcircle(ballx, bally, r); FlushBatchDraw(); //把之前所有的绘图内容显示出来 Sleep(3); //休眠,就是暂停,使小球慢慢地运动 } }; int Gaming() { Bricks brick; brick.drawallbricks(); Board board; setfillcolor(BLUE); solidrectangle(board.x, board.y, board.x + board.length, board.y + board.wide); Ball ball(board.wide); setfillcolor(RED); solidcircle(ball.ballx, ball.bally, ball.r); while (1) { //游戏结束条件 if (!ball.iscatch || brick.count == 0) { //本局结束后把当前小球和木板清除掉 setfillcolor(BLACK); solidcircle(ball.ballx, ball.bally, ball.r); solidrectangle(board.x, board.y, board.x + board.length, board.y + board.wide); if (brick.count > 0) return MessageBox(NULL, L"You Lose!", L"打砖块", MB_RETRYCANCEL); else if (brick.count == 0) return MessageBox(NULL, L"You Win!", L"打砖块", MB_RETRYCANCEL); } if (_kbhit()) //判断你是否按下键 按下返回1 没有返回0 { board.Move(); } ball.Move(brick, board); } } int main() { initgraph(WINDOW_WIDE, WINDOW_HEIGHT); //初始化窗口 while (1) { if (Gaming() == IDCANCEL) //点击 取消 return 0; } }
终于结束啦,我很高兴这次能与大家一起分享这个小游戏,最后谢谢大家了。
百度网盘 源码下载链接:http://pan.baidu.com/s/1gfIk6av 密码:obw4
相关文章推荐
- 使用C++与SFML编写一个简单的撞球游戏Part1——新建工程以及设置
- 使用C++与SFML编写一个简单的撞球游戏Part3——创建游戏启动界面
- 使用C++与SFML编写一个简单的撞球游戏Part6——添加弹板控制与弹球
- 使用C++与SFML编写一个简单的撞球游戏Part2——创建游戏窗口
- 使用C++与SFML编写一个简单的撞球游戏Part7——弹球的碰撞检测
- 使用C++与SFML编写一个简单的撞球游戏Part4——添加玩家弹板
- 使用C++与SFML编写一个简单的撞球游戏Part5——对象管理
- 使用C++与SFML编写一个简单的撞球游戏Part8——添加AI弹板
- C++编写简单的打靶游戏
- Linux下,使用C/C++编写一个简单的消息处理程序
- 用java编写的一个简单的猜字母游戏
- 用c++写一个简单的打字游戏
- 一个简单的打砖块游戏实现
- 用C++编写一个随机产生多个两位数四则运算式子的简单程序
- [入门教程]使用Cocos2d-html5游戏引擎编写一个简单的游戏 第一回合: 搭建开发环境
- 用C++编写一个简单的员工工资管理系统~
- c++编写一个简单的数据库程序
- 使用c++开发excel插件 (3.4、编写一个简单的动态链接库)
- 如何使用Createjs来编写HTML5游戏(六)完成一个简单的打飞机游戏(上)