第一次玩EasyX,写一个比较简单的消砖块游戏。

主函数包括Game的类的开始,运行和结束。

 1 #include "BrickElimination.h"
2
3 int main()
4 {
5 GameBrickElimination NewGame;
6
7 NewGame.game_start();
8 NewGame.game_run();
9 NewGame.game_over();
10
11 return 0;
12 }

game_start()是所有元素的初始化,包括图像,砖块,弹球和挡板。

game_run()是游戏的主体,包括刷新界面,更新球的运动情况等。

game_over()是游戏的结束,停掉绘制。

头文件,定义了所有使用的类。

  1 #ifndef _BRICK_ELIMINATION_
2 #define _BRICK_ELIMINATION_
3
4 /* Settings */
5 #define GRAPH_HEIGHT 480
6 #define GRAPH_WIDTH 720
7 #define BRICK_NUM 20
8 #define BAR_MOVE_SPEED 15
9 #define BAR_WIDTH (GRAPH_WIDTH/5)
10 #define BALL_MOVE_SPEED 1
11 #define BALL_RADIUS 20
12
13 #define BRICK_EXIST 1
14 #define BRICK_NOT_EXIST 0
15
16
17 /* type define */
18 typedef enum
19 {
20 Ball_Hit_Wall = 0,
21 Ball_Hit_Bar,
22 Ball_Hit_Brick,
23 Ball_Sill_Moving
24 }Ball_Hit_Type;
25
26 typedef struct
27 {
28 int left;
29 int right;
30 int top;
31 int bottom;
32 }Brick_Group;
33
34
35 /* class ball define */
36 class CBall
37 {
38 private:
39 int m_ball_x, m_ball_y;
40 int m_ball_vx, m_ball_vy;
41 int m_radius;
42
43 public:
44 CBall();
45 ~CBall();
46 void ball_init_v();
47 void ball_clean_v();
48 void ball_show_v();
49 void ball_move_v();
50 int get_x() { return m_ball_x; };
51 int get_y() { return m_ball_y; };
52 int get_r() { return m_radius; };
53 int get_vx() { return m_ball_vx; };
54 int get_vy() { return m_ball_vy; };
55 void set_vx(int vx) { m_ball_vx = vx; };
56 void set_vy(int vy) { m_ball_vy = vy; };
57
58 };
59
60 /* class brick define */
61 class CBrick
62 {
63 private:
64 Brick_Group Bricks[BRICK_NUM];
65 int m_isBrickExisted[BRICK_NUM];
66 int m_brick_height, m_brick_width;
67
68 public:
69 CBrick();
70 ~CBrick();
71 void brick_init_v();
72 void brick_clean_v();
73 void brick_show_v();
74 int isBrickExist(int i) { return m_isBrickExisted[i]; };
75 void setBrickExist(int i, int state) { m_isBrickExisted[i] = state; };
76 int bricks_left(int i) { return Bricks[i].left; };
77 int bricks_right(int i) { return Bricks[i].right; };
78 int bricks_top(int i) { return Bricks[i].top; };
79 int bricks_bottom(int i) { return Bricks[i].bottom; };
80 };
81
82 /* class bar define */
83 class CBar
84 {
85 private:
86 int m_bar_x, m_bar_y;
87 int m_bar_width, m_bar_height;
88 int m_bar_left, m_bar_right, m_bar_top, m_bar_bottom;
89
90 public:
91 CBar();
92 ~CBar();
93 void bar_init_v();
94 void bar_clean_v();
95 void bar_show_v();
96 void bar_move_v();
97 int get_left() { return m_bar_left; };
98 int get_right() { return m_bar_right; };
99 int get_top() { return m_bar_top; };
100 int get_bottom() { return m_bar_bottom; };
101 int get_width() { return m_bar_width; };
102 int get_height() { return m_bar_height; };
103 };
104
105 /* class game define */
106 class GameBrickElimination
107 {
108 private:
109 CBall ball;
110 CBar bar;
111 CBrick brick;
112
113 public:
114 GameBrickElimination();
115 ~GameBrickElimination();
116 Ball_Hit_Type check_ball_hit(Ball_Hit_Type isHit);
117 void game_start();
118 void game_run();
119 void game_over();
120 };
121
122 #endif

类的实现,有几个关键点。

1.使用BeginBatchDraw(),FlushBatchDraw(),EndBatchDraw()来不闪屏地刷新界面,原理是在旧位置上画黑色图形覆盖掉旧位置,同时画出新位置,然后批量绘制。

2.判断球的相撞,其实就是比较球和砖块,挡板的坐标。

3.球的位置通过坐标和速度更新,球反弹的效果通过撞击以后速度设为反方向来实现。使用一个标志量来判断某个砖块是否消失。

  1 /* BrickEliminationElements.cpp */
2
3 #include "BrickElimination.h"
4 #include <graphics.h>
5 #include <conio.h>
6 #include "windows.h"
7
8 /* class ball realization */
9 CBall::CBall()
10 {
11 }
12
13 CBall::~CBall()
14 {
15 }
16
17 void CBall::ball_init_v()
18 {
19 m_ball_x = GRAPH_WIDTH / 2;
20 m_ball_y = GRAPH_HEIGHT / 2;
21 m_ball_vx = BALL_MOVE_SPEED;
22 m_ball_vy = BALL_MOVE_SPEED;
23 m_radius = BALL_RADIUS;
24 }
25
26 void CBall::ball_clean_v()
27 {
28 setcolor(BLACK);
29 setfillcolor(BLACK);
30 fillcircle(m_ball_x, m_ball_y, m_radius);
31 }
32
33 void CBall::ball_show_v()
34 {
35 setcolor(YELLOW);
36 setfillcolor(GREEN);
37 fillcircle(m_ball_x, m_ball_y, m_radius);
38 }
39
40 void CBall::ball_move_v()
41 {
42 m_ball_x += m_ball_vx;
43 m_ball_y += m_ball_vy;
44 }
45
46 /* class brick realization */
47 CBrick::CBrick()
48 {
49 }
50
51 CBrick::~CBrick()
52 {
53 }
54
55 void CBrick::brick_init_v()
56 {
57 m_brick_width = GRAPH_WIDTH / BRICK_NUM;
58 m_brick_height = GRAPH_HEIGHT / BRICK_NUM;
59
60 for (int i = 0; i < BRICK_NUM; i++)
61 {
62 Bricks[i].left = i * m_brick_width;
63 Bricks[i].right = Bricks[i].left + m_brick_width;
64 Bricks[i].top = 0;
65 Bricks[i].bottom = m_brick_height;
66 m_isBrickExisted[i] = BRICK_EXIST;
67 }
68 }
69
70 void CBrick::brick_clean_v()
71 {
72 setcolor(BLACK);
73 setfillcolor(BLACK);
74
75 for (int i = 0; i < BRICK_NUM; i++)
76 {
77 if (m_isBrickExisted[i] == BRICK_NOT_EXIST)
78 {
79 fillrectangle(Bricks[i].left, Bricks[i].top, Bricks[i].right, Bricks[i].bottom);
80 }
81 else
82 {
83 /* do thing */
84 }
85 }
86 }
87
88 void CBrick::brick_show_v()
89 {
90 for (int i = 0; i < BRICK_NUM; i++)
91 {
92 if (m_isBrickExisted[i])
93 {
94 setcolor(WHITE);
95 setfillcolor(RED);
96 fillrectangle(Bricks[i].left, Bricks[i].top, Bricks[i].right, Bricks[i].bottom);
97 }
98 else
99 {
100 /* do thing */
101 }
102 }
103 }
104
105 /* class bar realization */
106 CBar::CBar()
107 {
108 }
109
110 CBar::~CBar()
111 {
112 }
113
114 void CBar::bar_init_v()
115 {
116 m_bar_width = BAR_WIDTH;
117 m_bar_height = GRAPH_HEIGHT / 20;
118 m_bar_x = GRAPH_WIDTH / 2;
119 m_bar_y = GRAPH_HEIGHT - m_bar_height / 2;
120 m_bar_left = m_bar_x - m_bar_width / 2;
121 m_bar_right = m_bar_x + m_bar_width / 2;
122 m_bar_top = m_bar_y - m_bar_height / 2;
123 m_bar_bottom = m_bar_y + m_bar_height / 2;
124 }
125
126 void CBar::bar_clean_v()
127 {
128 setcolor(BLACK);
129 setfillcolor(BLACK);
130 bar(m_bar_left, m_bar_top, m_bar_right, m_bar_bottom);
131 }
132
133 void CBar::bar_show_v()
134 {
135 setcolor(YELLOW);
136 setfillcolor(GREEN);
137 bar(m_bar_left, m_bar_top, m_bar_right, m_bar_bottom);
138 }
139
140 void CBar::bar_move_v()
141 {
142 char input;
143 if (_kbhit())
144 {
145 input = _getch();
146 if (input == 'a' && m_bar_left > 0)
147 {
148 m_bar_x -= BAR_MOVE_SPEED;
149 m_bar_left = m_bar_x - m_bar_width / 2;
150 m_bar_right = m_bar_x + m_bar_width / 2;
151 }
152 else if (input == 'd' && m_bar_right < GRAPH_WIDTH)
153 {
154 m_bar_x += BAR_MOVE_SPEED;
155 m_bar_left = m_bar_x - m_bar_width / 2;
156 m_bar_right = m_bar_x + m_bar_width / 2;
157 }
158 else
159 {
160 /* do thing */
161 }
162 }
163 else
164 {
165 /* do thing */
166 }
167 }
168
169 GameBrickElimination::GameBrickElimination()
170 {
171 }
172
173 GameBrickElimination::~GameBrickElimination()
174 {
175 }
176
177 Ball_Hit_Type GameBrickElimination::check_ball_hit(Ball_Hit_Type isHit)
178 {
179 switch (isHit)
180 {
181 case Ball_Hit_Wall:
182 {
183 //check ball hit wall or not
184 if ((ball.get_x() <= ball.get_r()) || (ball.get_x() >= GRAPH_WIDTH - ball.get_r()))
185 {
186 ball.set_vx(-ball.get_vx());
187 return Ball_Hit_Wall;
188 }
189 else
190 {
191 /* do nothing */
192 }
193
194 if ((ball.get_y() <= ball.get_r()) || (ball.get_y() >= GRAPH_HEIGHT - ball.get_r()))
195 {
196 ball.set_vy(-ball.get_vy());
197 return Ball_Hit_Wall;
198 }
199 else
200 {
201 /* do nothing */
202 }
203 break;
204 }
205 case Ball_Hit_Bar:
206 {
207 if (((ball.get_y() + ball.get_r() >= bar.get_top())
208 && (ball.get_y() + ball.get_r() < bar.get_bottom() - bar.get_height() / 3))
209 || ((ball.get_y() - ball.get_r() <= bar.get_bottom())
210 && (ball.get_y() - ball.get_r() > bar.get_top() - bar.get_height() / 3)))
211 {
212 if ((ball.get_x() > bar.get_left()) && (ball.get_x() < bar.get_right()))
213 {
214 ball.set_vy(-ball.get_vy());
215 return Ball_Hit_Bar;
216 }
217 else
218 {
219 /* do nothing */
220 }
221 }
222 else
223 {
224 /* do nothing */
225 }
226 break;
227 }
228 case Ball_Hit_Brick:
229 {
230 for (int i = 0; i < BRICK_NUM; i++)
231 {
232 if (brick.isBrickExist(i) == BRICK_EXIST)
233 {
234 if ((ball.get_y() <= brick.bricks_bottom(i) + ball.get_r())
235 && (ball.get_x() >= brick.bricks_left(i))
236 && (ball.get_x() <= brick.bricks_right(i)))
237 {
238 brick.setBrickExist(i, BRICK_NOT_EXIST);
239 ball.set_vy(-ball.get_vy());
240 return Ball_Hit_Brick;
241 }
242 else
243 {
244 /* do nothing */
245 }
246 }
247 else
248 {
249 /* do nothing */
250 }
251 }
252 break;
253 }
254 default:
255 {
256 break;
257 }
258 }
259 }
260
261 /* class game realization */
262 void GameBrickElimination::game_start()
263 {
264 ball.ball_init_v();
265 bar.bar_init_v();
266 brick.brick_init_v();
267
268 initgraph(GRAPH_WIDTH, GRAPH_HEIGHT);
269 BeginBatchDraw();
270 }
271
272 void GameBrickElimination::game_run()
273 {
274 while (1)
275 {
276 ball.ball_clean_v();
277 bar.bar_clean_v();
278 brick.brick_clean_v();
279
280 check_ball_hit(Ball_Hit_Wall);
281 ball.ball_move_v();
282
283 check_ball_hit(Ball_Hit_Bar);
284 bar.bar_move_v();
285
286 check_ball_hit(Ball_Hit_Brick);
287
288 ball.ball_show_v();
289 bar.bar_show_v();
290 brick.brick_show_v();
291
292 FlushBatchDraw();
293 Sleep(3);
294 }
295 }
296
297 void GameBrickElimination::game_over()
298 {
299 EndBatchDraw();
300 closegraph();
301 }

效果:

使用EasyX和C++写一个消砖块游戏的更多相关文章

  1. 在code.org上自己写一个flappy bird游戏

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:在code.org上自己写一个flappy bird游戏.

  2. JavaScript写一个连连看的游戏

    天天看到别人玩连连看, 表示没有认真玩过, 不就把两个一样的图片连接在一起么, 我自己写一个都可以呢. 使用Javascript写了一个, 托管到github, 在线DEMO地址查看:打开 最终的效果 ...

  3. 用Canvas写一个简单的游戏--别踩白块儿

    第一次写博客也不知怎么写,反正就按照我自己的想法来吧!怎么说呢?还是不要扯那些多余的话了,直接上正题吧! 第一次用canvas写游戏,所以挑个简单实现点的来干:别踩白块儿,其他那些怎么操作的那些就不用 ...

  4. 用Python写一个猜数字游戏

    2015.5.25第一天下载Python IDLE,写个猜数字的小游戏来熟悉这门语言: times=6 letters=[100] for i in range(1,times): a = input ...

  5. 使用Swift和SpriteKit写一个忍者游戏

    这篇文章的游戏使用SpriteKit和Swift语言来完毕. SpriteKit是苹果自己的游戏引擎,更能贴合iOS系统底层的API,只是架构和实现上都是模仿了Cocos2D.所以使用上事实上区别不大 ...

  6. python 写一个贪吃蛇游戏

    #!usr/bin/python #-*- coding:utf-8 -*- import random import curses s = curses.initscr() curses.curs_ ...

  7. [译]终极塔防——运用HTML5从头创建一个塔防游戏

    翻译共享一篇CodeProject的高星力作,原文地址:http://www.codeproject.com/Articles/737238/Ultimate-Tower-Defense 下载演示项目 ...

  8. 教你用Vue写一个开心消消乐

    之前做过一个算法题,算法要求就是写一个开心消消乐的逻辑算法,当时也是考虑了一段时间才做出来.后来想了想,既然核心算法都有了,能不能实现一个开心消消乐的小游戏呢,于是花了两天时间做了一个小游戏出来. 效 ...

  9. 从0开始写一个简单的vite hmr 插件

    从0开始写一个简单的vite hmr 插件 0. 写在前面 在构建前端项目的时候,除开基本的资源格式(图片,json)以外,还常常会需要导入一些其他格式的资源,这些资源如果没有第三方vite插件的支持 ...

随机推荐

  1. new Map()详细介绍与对比

      说明: Map结构提供了“值—值”的对应,是一种更完善的Hash结构实现.如果你需要“键值对”的数据结构,Map比Object更合适.它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串, ...

  2. 【python开发】迈出第一步,这可能是我唯一一次的Python开发了

    好久没写博了,今天就瞎唠唠吧 背景: 组内有个测试平台,是基于Python2+tornado 框架写的,之前自己维护了一套系统的UIweb自动化代码,现在需要集成进去.这很可能是自己唯一一次基于pyt ...

  3. Web测试和前端技术

    Html Form表单 用户需要输入内容的地方一般有一个表单元素 method:GET/POST action:要打开/提交的目文件 Table表格 检查表格数据和数据库的一致性 表格的布局检测:填满 ...

  4. cometoj(A-D+F+H)代码

    A #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> ...

  5. Mybatis-多对一和一对多

    多对一和一对多 目录 多对一和一对多 1. 复杂表的构建 2. 测试环境搭建 1. 导入Lombok 2. 新建实体类 3. 建立Mapper接口 4. 建立Mapper.xml文件 5. 在核心配置 ...

  6. 字符串split的用法

    拆分字符串:张三:20|李四:40|王五:40 这个可以使用两次分割,第一次使用 | 分割,放到arr数组里,然后使用循环对arr[i]进行使用:分割 public static void main( ...

  7. python应用 曲线拟合04

    python应用 曲线拟合04 → 多项式拟合 主要是使用 numpy 库中的 polyfit() 函数,见第 66 行, z = np.polyfit(x_proton, y, 3) ,其中待拟合曲 ...

  8. C#开发PACS医学影像处理系统(三):界面布局之工具栏

    工具栏布局采用WPF中Grid作为容器,按钮采用自定义样式和图标,并采用Separator分割线: XAML设计器代码: 其中  Style="{StaticResource ButtonS ...

  9. Spring基于XML的IOC环境搭建及入门

    一.使用Maven构建Java项目 * 项目目录结构 1. 在sun.service包下创建UserDao接口和接口实现类: UserDao接口: package sun.service; /** * ...

  10. Python实现GUI开发 PySide2&PyQt环境配置

    更新于2020-09-15 - 18:50:37 [前言] 关于Python开发GUI图形界面程序的问题,大概是19年十分困扰我,主要是没有经验以及缺乏高效简洁的视频或教学文档,导致在19年中秋前后花 ...