【C++项目实战】贪吃蛇小游戏
一、引言
贪吃蛇,这款经典的电子游戏,自1976年诞生以来,一直受到全球玩家的喜爱。它的规则简单,玩法直观,但同时也充满了挑战性。在这篇文章中,我们将一起探索如何开发一个贪吃蛇游戏,无论是作为编程新手的练手项目,还是作为游戏开发爱好者的娱乐之作,都是一个不错的选择。
二、贪吃蛇游戏基本规则
游戏规则
- 游戏目标:控制一条蛇在屏幕上移动,吃掉出现的食物,每吃一个食物,蛇的长度就会增加一节。
- 控制方式:通过键盘的上下左右键控制蛇的移动方向。
- 游戏结束条件:蛇撞到屏幕边界或者自己的身体时,游戏结束。
基本思路
- 使用数组或链表来表示蛇的身体。
- 通过改变蛇头的位置来控制蛇的移动。
- 使用随机数来生成食物的位置。
- 检测蛇头与食物、墙壁和自身身体的碰撞。
三、代码
首先绘制一个范围,确定面积多大
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#include<conio.h>
//设置地图边界
#define W 120
#define H 30
//测试Ui界面多大
void text_ui()
{
for (int i = 0;i < H; i++)
{
for (int j = 0;j < W; j++)
{
printf("=");
}
printf("\n");
}
}
int main()
{
text_ui();
return 0;
}
得到结果如下:
整个游戏复制以下代码运行即可:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#include<conio.h>
//设置地图边界
#define W 120
#define H 30
//设置贪吃蛇结构体
typedef struct _body
{
int x; //坐标x
int y; //坐标y
}BODY;
typedef struct snake
{
BODY list[W*H]; //贪吃蛇最大沾满整个地图
int size; //实际身体个数。蛇头 @,蛇身 *
BODY food; //食物 #
COORD coord; //定位光标
int dx; //移动方向
int dy; //移动方向
BODY tail; //记录蛇尾(用于清除蛇尾痕迹)
int score; //记录分数
}SNAKE;
//食物函数
void init_food(BODY* food)
{
//设置随机数种子
srand(time(NULL));
//设置食物坐标
food->x = rand() % (W - 1) +1;
food->y = rand() % (H - 1) +1;
}
//初始化蛇的函数
void init_snake(SNAKE *snake)
{
//设置蛇头与蛇尾的位置
snake->list[0].x = W / 2;
snake->list[0].y = H / 2;
snake->list[1].x = W / 2 - 1;
snake->list[1].y = H / 2 - 1;
snake->size = 2;
//设置移动方向
snake->dx = 1;
snake->dy = 0;
snake->score = 0;
//设置食物位置
init_food(&(snake->food));
}
//展示UI函数
void show_ui(SNAKE* snake)
{
//显示蛇
for (int i = 0;i < snake->size;i++)
{
snake->coord.X = snake->list[i].x;
snake->coord.Y = snake->list[i].y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
if (i == 0) //显示蛇头
{
printf("@");
}
else
{
printf("*");
}
}
//显示食物
snake->coord.X = snake->food.x;
snake->coord.Y = snake->food.y;
//定位光标位置
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
printf("#");
//清除蛇尾痕迹
snake->coord.X = snake->tail.x;
snake->coord.Y = snake->tail.y;
//定位光标位置
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
printf(" ");
}
void show_wall()
{
for (int i = 0;i <= H; i++)
{
for (int j = 0;j <= W; j++)
{
if (i == 0 || j == 0 || i == H || j == W)
{
printf("+");
}
else
{
printf(" ");
}
}
printf("\n");
}
}
/*
测试Ui界面多大
void text_ui()
{
for (int i = 0;i < H; i++)
{
for (int j = 0;j < W; j++)
{
printf("=");
}
printf("\n");
}
}
*/
void hide_cur()//隐藏光标
{
CONSOLE_CURSOR_INFO cci;
cci.dwSize = sizeof(cci);
cci.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
}
void move_snake(SNAKE* snake) //移动函数
{
snake->tail = snake->list[snake->size - 1];
for (int i = snake->size - 1; i > 0; i--)
{
snake->list[i] = snake->list[i - 1];
}
snake -> list[0].x += snake->dx;
snake -> list[0].y += snake->dy;
}
void contorl_snake(SNAKE *snake)
{
char key=0;
while (_kbhit()) //判断是否按下按键,按下不等于0
{
key = _getch();
}
switch (key)
{
case'w':
snake -> dy = -1;
snake -> dx = 0;
break;
case's':
snake->dy = 1;
snake->dx = 0;
break;
case'a':
snake->dy = 0;
snake->dx = -1;
break;
case'd':
snake->dy = 0;
snake->dx = 1;
break;
}
}
void snake_eat_food(SNAKE* snake) //吃食物函数
{
if (snake->list[0].x== snake->food.x && snake->list[0].y == snake->food.y)
{
snake->size++;
init_food(&(snake->food));
snake->score += 10;
}
}
void game_over(SNAKE *snake)
{
snake->coord.X = 110;
snake->coord.Y = 65;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
printf("游戏结束,总分数:%d\n", snake->score);
}
void start_game(SNAKE *snake)
{
while (snake->list[0].x>0 && snake->list[0].x<W &&
snake->list[0].y>0 && snake->list[0].y < H)
{
show_ui(snake); //显示蛇和食物
contorl_snake(snake); //控制蛇
snake_eat_food(snake); //判断是否吃到食物
move_snake(snake); //移动蛇
Sleep(100); //延时100毫秒
}
game_over(snake);
}
int main(int argc, char* argv[])
{
hide_cur(); //隐藏光标
//text_ui();
SNAKE* snake = (SNAKE*)malloc(sizeof(SNAKE));
init_snake(snake); //初始化
show_wall(); //显示墙
start_game(snake);
free(snake);
while (1);
return 0;
}
代码解析
-
头文件包含:
stdio.h
:标准输入输出头文件。string.h
:字符串操作头文件。stdlib.h
:标准库头文件,包含内存分配等函数。time.h
:时间操作头文件,用于生成随机数。windows.h
:Windows API 头文件,用于控制台操作。conio.h
:控制台输入输出头文件,用于非缓冲输入。
-
宏定义:
W
和H
分别定义了游戏地图的宽度和高度。
-
结构体定义:
BODY
:用于存储蛇的身体部分的坐标。SNAKE
:包含蛇的身体、食物、方向、分数等信息。
-
函数定义:
init_food
:初始化食物的位置。init_snake
:初始化蛇的位置和方向。show_ui
:显示蛇和食物。show_wall
:显示游戏的边界。hide_cur
:隐藏控制台光标。move_snake
:根据蛇的方向移动蛇的身体。contorl_snake
:通过键盘输入控制蛇的移动方向。snake_eat_food
:判断蛇是否吃到食物,并更新蛇的长度和分数。game_over
:游戏结束时显示分数。start_game
:游戏的主循环,控制游戏的流程。
-
主函数:
main
:程序的入口点,初始化游戏,隐藏光标,显示边界,并开始游戏循环。