一、基本思路
制作贪吃蛇游戏,首先必须要有的材料是蛇和得分的食物;其次是游戏逻辑,1.要能使用键盘控制蛇的移动;2.食物被吃掉要能再次生成并且蛇要做出相应变化;3.蛇咬到自己的身体和墙会死亡;最后是图形界面的显示。
二、蛇和食物
蛇和食物使用结构体来储存,代码比较简单。
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
|
#include <graphics.h> #include <stdio.h> #include <time.h> #include <conio.h> #define SIZE 30 #define N 1000 //蛇的长度限制 struct Coor { int x; int y; }; enum Ch{ up = 72,down = 80,left = 75,right = 77,P=112 }; //ASCII码 枚举 struct Snake { int n; Coor scr[N]; Ch ch; //蛇的方向 }snake; struct Food { Coor fsr; //食物坐标 int flag; //标记食物是否被吃掉 }food; |
三、游戏逻辑实现
1. 键盘控制蛇的移动
蛇的移动和方向改变主要是依靠SnakeMove和ChangeSnake两个函数实现,ChangeSnake函数通过键盘输入的ch值来判断用户对蛇方向的控制,从而修改snake.ch(蛇的方向)的值,然后SnakeMove函数通过修改后的snake.ch的值来控制蛇的移动,如果没有新的ch值从键盘输入,蛇会一直保持原来的方向移动到地图边界。
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
47
48
49
50
|
void SnakeMove() { for ( int i = snake.n - 1; i > 0; i--) { snake.scr[i].x = snake.scr[i - 1].x; snake.scr[i].y = snake.scr[i - 1].y; } switch (snake.ch) { case up: snake.scr[0].y -= SIZE; break ; case down: snake.scr[0].y += SIZE; break ; case left: snake.scr[0].x -= SIZE; break ; case right: snake.scr[0].x += SIZE; break ; } } void ChangeSnake() { switch (getch()) { case 72: if (snake.ch != down) { snake.ch = up; } break ; case 80: if (snake.ch != up) { snake.ch = down; } break ; case 75: if (snake.ch != right) { snake.ch = left; } break ; case 77: if (snake.ch != left) { snake.ch = right; } break ; case 112: system ( "pause" ); } } |
2. 食物被吃的触发事件
当食物被蛇吃掉(蛇头坐标和食物坐标重合),蛇身长度加一,食物存在标记置0;
1
2
3
4
5
6
|
void EatFood() { if (snake.scr[0].x == food.fsr.x&&snake.scr[0].y == food.fsr.y) { snake.n++; food.flag = 0; } } |
3. 游戏结束事件
当蛇头触碰边界或者自己的身体(蛇头坐标超出地图边界或与蛇身任一坐标重合),窗口打印OverGame函数中预设的界面,并且关闭程序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
void GameBreak() { //撞墙 if (snake.scr[0].y < -1 || snake.scr[0].y>706 || snake.scr[0].x < -1 || snake.scr[0].x>946) { OverGame(); } //撞身体 for ( int i = snake.n - 1; i > 0; i--) { if (snake.scr[0].x == snake.scr[i].x&&snake.scr[0].y == snake.scr[i].y) { OverGame(); } } } void OverGame() { cleardevice(); settextcolor(RED); settextstyle(100, 0, L "黑体" ); outtextxy(400, 250, L "菜" ); Sleep(2000); exit (0); } |
四、图形界面的显示
1. 素材准备
需要准备的素材有蛇头的图片(如果不是对称图形,可以准备四个不同方向的图片),蛇身的图片(如果制作蛇头和蛇身一样的话则可以直接使用蛇头的图片),得分果实的图片。
2.背景制作及图片导入
将所有图片放入vs的项目文件夹即可直接在代码中通过loadimage函数对图片名字调用,GameInit函数主要进行游戏初始化,将蛇长度置为一,坐标置为(0,0),食物存在标记置零,打印游戏欢迎界面(GameStart函数)。
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
|
IMAGE snakeleft, snakeright, snakedown, snakeup, she, shiwu; void GameInit() { initgraph(960, 720); setbkcolor(BLACK); cleardevice(); loadimage(&snakeleft, L "蛇头.jpg" , SIZE, SIZE); loadimage(&snakeright, L "蛇头.jpg" , SIZE, SIZE); loadimage(&snakeup, L "蛇头.jpg" , SIZE, SIZE); loadimage(&snakedown,L "蛇头.jpg" , SIZE, SIZE); loadimage(&she, L "蛇身1.jpg" , SIZE, SIZE); loadimage(&shiwu, L "果实.jpg" , SIZE, SIZE); //蛇初始化 snake.scr[0].x = 0; snake.scr[0].y = 0; snake.n = 1; snake.ch = P; food.flag = 0; GameStart(); } void GameStart() { cleardevice(); settextcolor(WHITE); settextstyle(50, 0, L "黑体" ); outtextxy(350, 250, L "游戏开始" ); outtextxy(300, 400, L "按“P”键暂停" ); system ( "pause" ); } |
3.蛇和食物的打印
当食物存在标记为0时调用FoodCoor函数,随机重置食物坐标并且将标记置1,图片的打印主要依靠putimage函数,函数用法比较简单,这里就不多说了。
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
|
void SnakePaint(IMAGE snakeright, IMAGE snakeleft, IMAGE snakedown, IMAGE snakeup, IMAGE she) { switch (snake.ch) { case up: putimage(snake.scr[0].x, snake.scr[0].y, &snakeup); break ; case down: putimage(snake.scr[0].x, snake.scr[0].y, &snakedown); break ; case left: putimage(snake.scr[0].x, snake.scr[0].y, &snakeleft); break ; case right: putimage(snake.scr[0].x, snake.scr[0].y, &snakeright); break ; } for ( int i=snake.n-1;i>0;i--){ putimage(snake.scr[i].x, snake.scr[i].y, &she); } } void FoodCoor() { srand ((unsigned int ) time (NULL)); food.fsr.x = ( rand () % 31 + 1)*SIZE; food.fsr.y = ( rand () % 23 + 1)*SIZE; food.flag = 1; //有食物 } void FoodPaint(IMAGE shiwu) { putimage(food.fsr.x, food.fsr.y, &shiwu); } |
五、游戏的运行
首先调用GameInit函数进行初始化,第一层while保证游戏始终运行,第二层while是保证当没有键盘输入时,游戏会按设计好的逻辑运行和判断,而当有键盘输入时,调用ChangeSnake函数判断用户对蛇的控制,从而进行相应的改变。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
int main() { GameInit(); while (1) { while (!kbhit()) { if (food.flag == 0) FoodCoor(); cleardevice(); FoodPaint(shiwu); //绘制食物 SnakeMove(); SnakePaint(snakeright, snakeleft, snakedown, snakeup, she); Sleep(200-snake.n*5); EatFood(); GameBreak(); } ChangeSnake(); } return 0; } |
六、成品演示
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/RanDoll_/article/details/111751474