始祖是美国英宝格公司(en:Atari Games,ja:アタリ (ゲーム))于1976年推出的街机游戏“Breakout”(en:Breakout),由该公司在1972年发行的“PONG”(en:PONG,ja:ポン (ゲーム),世界上第一款电子游戏,类似台球)改良而来。相较于其前作,一个人就可以玩与变化丰富这两项特点让Breakout相当卖座,使各家公司竞相模仿。 因为规则简单与游戏性,现在许多移动电话都有内建打砖块游戏,也有许多因特网小游戏版本,目前在网上可以轻易查到。
我们今天就来自己写经典游戏《打砖块》
游戏目标:消除所有的方块即可过关。操作指南:游戏中使用键盘方向键←→控制移动
OK,了解游戏的基本操作以及游戏玩法之后就可以开始我们的编程之旅了,今天我会一步代码一个图片的来分布展示,希望这种方式可以让大家更容易的理解,如果有其他更好的方式,也欢迎大家向我提出建议
首先是创建一个游戏窗口,我们用EasyX图形库来做,只需要一行代码
1
|
hwnd = initgraph(800, 800); |
这样我们就创建了一个800*800的窗口,非常简单,非常好用,这也是非常适合初学者去尝试的,这里我们写在主函数里面就可以了
接下来就是我们的老朋友结构体了,木板、球、以及砖块,这没什么好说的,不管啥项目用结构体都是很常见的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
//木板的过程 struct Board { int x; int y; int speed; COLORREF color; int width; int height; }; //struct Board board = { 300, 800 - 25,1, WHITE, 200, 25 }; struct Board* createBoard( int x, int y, int speed, COLORREF color, int width, int height) { struct Board* pBoard = ( struct Board*) malloc ( sizeof ( struct Board)); //结构体指针->成员 ->指针指向运算符 //(*指针).成员; pBoard->x = x; pBoard->y = y; pBoard->speed = speed; pBoard->color = color; //结构体变量.成员 (*pBoard).width = width; (*pBoard).height = height; return pBoard; } //球: struct Ball { int x; int y; int r; //半径 int dx; int dy; COLORREF color; }; struct Ball* createBall( int x, int y, int r, int dx, int dy, COLORREF color) { struct Ball* pBall = ( struct Ball*) malloc ( sizeof ( struct Ball)); pBall->x = x; pBall->y = y; pBall->r = r; pBall->dx = dx; pBall->dy = dy; pBall->color = color; return pBall; } |
后面就是我们来画我们的游戏界面了(砖块、球、以及木板),这我是分开写的,可以更好的理解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
void drawMap() { setlinestyle(PS_SOLID, 2); setlinecolor(WHITE); for ( int i = 0; i < 5; i++) { for ( int j = 0; j < 8; j++) { int x = 100 * j; //j=x/100 int y = 25 * i; //i=y/i switch (map[i][j]) //map[i][j]!=0 { case 0: //做消除用的 break ; case 1: setfillcolor(YELLOW); fillrectangle(x, y, x + 100, y + 25); break ; case 2: setfillcolor(LIGHTBLUE); fillrectangle(x, y, x + 100, y + 25); break ; case 3: setfillcolor(LIGHTGREEN); fillrectangle(x, y, x + 100, y + 25); break ; } } } } void drawBoard( struct Board* pBoard) { setfillcolor(pBoard->color); fillrectangle(pBoard->x, pBoard->y, pBoard->x + pBoard->width, pBoard->y + pBoard->height); } void drawBall( struct Ball* pBall) { setfillcolor(pBall->color); solidcircle(pBall->x, pBall->y, pBall->r); } |
做完之后我们就可以看到这样的界面了
到现在我们的基本游戏界面就已经出来了,现在差的就是判断逻辑问题了,这也是我们的重点中的重点,包括球的移动、球的弹射角度、木板的移动、砖块的消失、游戏的输赢判断都需要我们考虑到,希望大家可以好好看,好好学! 首先是木板的移动函数,我们就简单控制了,因为他只用左右移就行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
//木板的按键操作 void keyDown( struct Board* pBoard) { //C语言: scanf函数 getch() getchar() gets() //异步的按键操作 if (GetAsyncKeyState( 'A' ) || GetAsyncKeyState(VK_LEFT) && pBoard->x >= 0) { pBoard->x -= pBoard->speed; } if (GetAsyncKeyState( 'D' ) || GetAsyncKeyState(VK_RIGHT) && pBoard->x <= 800 - 200) { pBoard->x += pBoard->speed; } } |
接下来就是球的移动函数
1
2
3
4
5
6
7
8
9
10
11
12
|
void moveBall( struct Ball* pBall, struct Board* pBoard) { if (pBall->x - pBall->r <= 0 || pBall->x + pBall->r >= 800) { pBall->dx = -pBall->dx; } if (pBall->y - pBall->r <= 0 || hitBoard(pBall, pBoard) || hitBricks(pBall)) { pBall->dy = -pBall->dy; } pBall->x += pBall->dx; pBall->y += pBall->dy; |
球的反射以及撞击木板时的判断函数
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//1.反射 //2.撞击木板 int hitBoard( struct Ball* pBall, struct Board* pBoard) { if (pBall->y + pBall->r == pBoard->y) //y满足 { if (pBall->x >= pBoard->x && pBall->x <= pBoard->x + pBoard->width) { return 1; } } return 0; } |
球撞击砖块的判断函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
//3.撞击砖块 int hitBricks( struct Ball* pBall) { //1.算出球的行的列是属于地图 int ballJ = pBall->x / 100; int ballI = (pBall->y - pBall->r) / 25; //2.当前下标下,数组中不等于表示有砖块需要反射 if (ballJ < 8 && ballI < 5 && map[ballI][ballJ] != 0) { map[ballI][ballJ] = 0; return 1; } return 0; } |
在这个过程中还需要一个定时器,我们来定义一个定时器,记住调用头文件<time.h>
1
2
3
4
5
6
7
8
9
10
11
|
int Timer( time_t num, int id) { static time_t start[10]; time_t end = clock (); if (end - start[id]>num) { start[id] = end; return 1; } return 0; } |
游戏结束的判断函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
int gameOver() { for ( int i = 0; i < 5; i++) { for ( int j = 0; j < 8; j++) { if (map[i][j] != 0) { return 0; } } } return 1; } |
最后是我们的主函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
int main() { srand ((unsigned int ) time (0)); //设置随机数的范围跟随时间改变而改变 hwnd = initgraph(800, 800); struct Board* pBoard = createBoard(300, 800 - 25, 5, WHITE, 200, 25); struct Ball* pBall = createBall(400, 600, 15, 5, -5, RED); initMap(); BeginBatchDraw(); while (1) { cleardevice(); drawMap(); drawBoard(pBoard); drawBall(pBall); if (Timer(10, 0)) moveBall(pBall, pBoard); keyDown(pBoard); if (die(pBall)) { MessageBox(hwnd, L "you die" , L "gameOver" , MB_OK); exit (0); } if (gameOver()) { MessageBox(hwnd, L "win game" , L "gameOver" , MB_OK); exit (0); } FlushBatchDraw(); } EndBatchDraw(); closegraph(); return 0; } |
经典游戏《打砖块》完成,OK,简单总结一下,代码不难,逻辑也不难,重要是大家一定要自己动手去做,这是毋庸置疑的,编程没有捷径,只有不断的学习熟练,加强自己的能力,有条件的话找个老师的话效果会更好,好了,希望大家可以在这里得到自己想要的知识以及快乐吧,也希望大家可以给UP主一个关注,非常感谢大家了!!!
点击下方链接进入视频讲解
C/C++游戏《打砖块》视频详细教程https://www.bilibili.com/video/BV1ur4y1C727/
https://www.bilibili.com/video/BV1ur4y1C727/
到此这篇关于C语言 小游戏打砖块实现流程详解的文章就介绍到这了,更多相关C语言 打砖块内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/weixin_45713725/article/details/121286456