大家好,这一篇博客讲的是我对 C语言贪吃蛇 的理解。以下代码使用的是 VS2022环境下的 C语言,如果有错误,还请读者大大们指出。
声明
这篇博客中的贪吃蛇核心代码参考自【河海大学·童晶】做游戏,学编程(C语言)P38 课时35.贪吃蛇
游戏演示
贪吃蛇演示视频
游戏基础内容实现
首先准备好 game.h、game.c、test.c。
伪图形界面实现
在game.h中:
#pragma
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <time.h> // 获取时间戳的准备
#include <windows.h> // 使用gotoxy()、HideCursor()函数的准备
#include <conio.h> // khbit()、getch()函数准备
#include <stdlib.h> // srand()、rand()函数准备
#define HIGH 20 // 画面的高
#define WIGHT 30 // 画面的宽
void game(); // 游戏框架
void HideCursor(); // 隐藏光标
void gotoxy(int x, int y); // 固定画面
在test.c中:
#include "game.h"
void explain()
{
printf("********** 操作说明 **********\n");
printf("* 移动键(小写) 上:w 下:s *\n");
printf("* 左:a 右:d *\n");
printf("* 空格:加速开关 *\n");
printf("* 加速吃果实分数为2,反之为1 *\n");
printf("* 小写字母j:暂停开关 *\n");
printf("********** 操作说明 **********\n");
printf("------------------------------\n");
printf("空格返回\n");
while (_getch() != ' ')
Sleep(10);
system("cls");
}
void menu()
{
int inputY = 0;
char arr[3][13] = { "开始游戏", "操作说明", "结束游戏" };
while (1) // 伪图形处理
{
gotoxy(0, 0);
// 打印
printf("**********************\n");
if (inputY == 0) // \033方式改变字体颜色
printf("*****\033[41m %10s \033[0m*****\n", &arr[0][0]);
else
printf("***** %-11s*****\n", &arr[0][0]);
if (inputY == 1)
printf("*****\033[41m %10s \033[0m*****\n", &arr[1][0]);
else
printf("***** %-11s*****\n", &arr[1][0]);
if (inputY == 2)
printf("*****\033[41m %10s \033[0m*****\n", &arr[2][0]);
else
printf("***** %-11s*****\n", &arr[2][0]);
printf("**********************\n");
printf("上:w 下:s\n");
printf("空格键确定\n");
// 输入
char ch = _getch();
// 执行
switch (ch)
{
case 'w':
inputY = (inputY - 1 + 3) % 3;
break;
case 's':
inputY = (inputY + 1) % 3;
break;
case ' ':
if (inputY == 0)
{
system("cls");
game();
}
else if (inputY == 1)
{
system("cls");
explain();
}
else if (inputY == 2)
return;
}
// 帧数限制
Sleep(10);
}
}
void game()
{
}
void test()
{
HideCursor();
srand((unsigned int)time(NULL)); // 获得时间戳以生成随机数
menu();
}
int main()
{
test();
return 0;
}
在game.c中:
#include "game.h"
void gotoxy(int x, int y) // 光标移动到(x,y)的位置,可以让画面刷新
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);
}
void HideCursor() // 隐藏光标
{
CONSOLE_CURSOR_INFO cursor_info = { 1, 0 }; // 第二个值为0表示隐藏光标
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
初始化与打印
在game.h中:
void init(int frame[HIGH][WIGHT]); // 游戏初始化
void display(int frame[HIGH][WIGHT]); // 画面展示
在game.c中:
void init(int frame[HIGH][WIGHT])
{
// 初始化周围墙壁
for (int i = 0; i < HIGH; i++)
for (int j = 0; j < WIGHT; j++)
frame[i][j] = ((!i || i == HIGH - 1 || !j || j == WIGHT - 1) ? -1 : 0);
// 初始化蛇身蛇头
for (int i = 1; i <= 4; i++) // 这样蛇尾最大,方便查找
frame[HIGH / 2][WIGHT / 2 - i] = i;
// 生成食物
// fruitGenerate(frame);
}
void display(int frame[HIGH][WIGHT])
{
for (int i = 0; i < HIGH; i++)
{
for (int j = 0; j < WIGHT; j++)
{ // 这里采用数字记录逻辑,显示时用符号
if (frame[i][j] == 0) // 打印空白
printf(" ");
else if (frame[i][j] == -1) // 打印墙壁
printf("#");
else if (frame[i][j] == 1) // 打印蛇头
printf("@");
else if (frame[i][j] > 1) // 打印蛇身
printf("O");
else if (frame[i][j] == -2) // 打印食物
printf("F");
}
printf("\n");
}
}
在test.c中:
void game()
{
int frame[HIGH][WIGHT] = { 0 };
init(frame);
while (1)
{
gotoxy(0, 0); // 固定画面
display(frame);
Sleep(200);
}
}
生成果实
在game.h中:
void fruitGenerate(int frame[HIGH][WIGHT]); // 生成果实
在game.c中:
void fruitGenerate(int frame[HIGH][WIGHT])
{
while (1)
{
int y = rand() % (HIGH - 2) + 1;
int x = rand() % (WIGHT - 2) + 1;
if (frame[y][x] == 0) // 当放入的地方为空地
{
frame[y][x] = -2;
break;
}
}
}
蛇自动移动与检测游戏状态(重点)
这里需要细讲一下:
如图,-1为墙壁,-2为果实,1为蛇头,2、3、4为蛇身,空白格子为0。
在game.h中:
int snakeAutomaticMove(int frame[HIGH][WIGHT], int moveDirection); // 蛇自动移动
int detectGameState(int frame[HIGH][WIGHT], int newHeadY, int newHeadX, int tailY, int tailX); // 检测游戏状态
在game.c中:
int snakeAutomaticMove(int frame[HIGH][WIGHT], int moveDirection) // 蛇自动移动
{
// 存储蛇头位置
int headX = 0;
int headY = 0;
// 存储蛇尾位置
int tailX = 0;
int tailY = 0;
int max = 0;
// 查找
for (int i = 1; i < HIGH - 1; i++)
{
for (int j = 1; j < WIGHT - 1; j++)
{
// 第一步:蛇头蛇身+1
frame[i][j] > 0 ? frame[i][j]++ : 0;
// 第二步:
// 记录蛇头
if (frame[i][j] == 2)
{
headX = j;
headY = i;
}
// 记录蛇尾
if (frame[i][j] > max)
{
max = frame[i][j];
tailX = j;
tailY = i;
}
}
}
// 第三步:
// 存储新蛇头
int newHeadY = 0;
int newHeadX = 0;
switch (moveDirection)
{
case 1: // 上
newHeadY = headY - 1;
newHeadX = headX;
break;
case 2: // 下
newHeadY = headY + 1;
newHeadX = headX;
break;
case 3: // 左
newHeadY = headY;
newHeadX = headX - 1;
break;
case 4: // 右
newHeadY = headY;
newHeadX = headX + 1;
break;
}
// 检测游戏状态并返回
return detectGameState(frame, newHeadY, newHeadX, tailY, tailX);
}
int detectGameState(int frame[HIGH][WIGHT], int newHeadY, int newHeadX, int tailY, int tailX)
{
// 当蛇吃到食物不用去掉旧蛇尾
if (frame[newHeadY][newHeadX] == -2)
{
fruitGenerate(frame); // 重新生成果实
}
else // 去掉旧蛇尾
frame[tailY][tailX] = 0;
// 吃到自己 或 撞墙
if (frame[newHeadY][newHeadX] > 0 || frame[newHeadY][newHeadX] == -1)
return 0;
else // 放置新蛇头
frame[newHeadY][newHeadX] = 1;
return 1;
}
在test.c中:
void game()
{
// 开始移动方向为右
int moveDirection = 4;
// 检测游戏状态
int detect = 1;
int frame[HIGH][WIGHT] = { 0 };
init(frame);
while (1)
{
gotoxy(0, 0); // 固定画面
detect = snakeAutomaticMove(frame, moveDirection);
display(frame);
if (!detect)
{
printf("游戏结束,按空格返回\n");
while (_getch() != ' ')
Sleep(10);
system("cls");
break;
}
// 帧数限制
Sleep(200);
}
}
玩家操作
玩家操作主要是改变蛇自动移动的方向。
在game.h中:
void playerMove(int* moveDirection); // 玩家操作
在game.c中:
void playerMove(int* moveDirection)
{
char input = _getch();
// 确定移动方向 且 禁止反方向移动
if (input == 'w' && *moveDirection != 2) // 上
*moveDirection = 1;
else if (input == 's' && *moveDirection != 1) // 下
*moveDirection = 2;
else if (input == 'a' && *moveDirection != 4) // 左
*moveDirection = 3;
else if (input == 'd' && *moveDirection != 3) // 右
*moveDirection = 4;
}
在test.c中:
void game()
{
// 开始移动方向为右
int moveDirection = 4;
// 检测游戏状态
int detect = 1;
int frame[HIGH][WIGHT] = { 0 };
init(frame);
while (1)
{
gotoxy(0, 0); // 固定画面
detect = snakeAutomaticMove(frame, moveDirection);
display(frame);
if (!detect)
{
printf("游戏结束,按空格返回\n");
while (_getch() != ' ')
Sleep(10);
system("cls");
break;
}
if (_kbhit()) // 检测玩家键盘是否有输入
playerMove(&moveDirection);
// 帧数限制
Sleep(200);
}
}
基础内容源代码
对于game.h
#pragma
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <time.h> // 获取时间戳的准备
#include <windows.h> // 使用gotoxy()、HideCursor()函数的准备
#include <conio.h> // khbit()、getch()函数准备
#include <stdlib.h> // srand()、rand()函数准备
#define HIGH 20 // 画面的高
#define WIGHT 30 // 画面的宽
void game(); // 游戏框架
void HideCursor(); // 隐藏光标
void gotoxy(int x, int y); // 固定画面
void init(int frame[HIGH][WIGHT]); // 游戏初始化
void display(int frame[HIGH][WIGHT]); // 画面展示
void fruitGenerate(int frame[HIGH][WIGHT]); // 生成果实
int snakeAutomaticMove(int frame[HIGH][WIGHT], int moveDirection); // 蛇自动移动
int detectGameState(int frame[HIGH][WIGHT], int newHeadY, int newHeadX, int tailY, int tailX); // 检测游戏状态
void playerMove(int* moveDirection); // 玩家操作
对于test.c
#include "game.h"
void explain()
{
printf("********** 操作说明 **********\n");
printf("* 移动键(小写) 上:w 下:s *\n");
printf("* 左:a 右:d *\n");
printf("* 空格:加速开关 *\n");
printf("* 加速吃果实分数为2,反之为1 *\n");
printf("* 小写字母j:暂停开关 *\n");
printf("********** 操作说明 **********\n");
printf("------------------------------\n");
printf("空格返回\n");
while (_getch() != ' ')
Sleep(10);
system("cls");
}
void menu()
{
int inputY = 0;
char arr[3][13] = { "开始游戏", "操作说明", "结束游戏" };
while (1) // 伪图形化
{
gotoxy(0, 0);
// 打印
printf("**********************\n");
if (inputY == 0)
printf("*****\033[41m %10s \033[0m*****\n", &arr[0][0]);
else
printf("***** %-11s*****\n", &arr[0][0]);
if (inputY == 1)
printf("*****\033[41m %10s \033[0m*****\n", &arr[1][0]);
else
printf("***** %-11s*****\n", &arr[1][0]);
if (inputY == 2)
printf("*****\033[41m %10s \033[0m*****\n", &arr[2][0]);
else
printf("***** %-11s*****\n", &arr[2][0]);
printf("**********************\n");
printf("上:w 下:s\n");
printf("空格键确定\n");
// 输入
char ch = _getch();
// 执行
switch (ch)
{
case 'w':
inputY = (inputY - 1 + 3) % 3;
break;
case 's':
inputY = (inputY + 1) % 3;
break;
case ' ':
if (inputY == 0)
{
system("cls");
game();
}
else if (inputY == 1)
{
system("cls");
explain();
}
else if (inputY == 2)
return;
}
// 帧数限制
Sleep(10);
}
}
void game()
{
// 开始移动方向为右
int moveDirection = 4;
// 检测游戏状态
int detect = 1;
int frame[HIGH][WIGHT] = { 0 };
init(frame);
while (1)
{
gotoxy(0, 0); // 固定画面
detect = snakeAutomaticMove(frame, moveDirection);
display(frame);
if (!detect)
{
printf("游戏结束,按空格返回\n");
while (_getch() != ' ')
Sleep(10);
system("cls");
break;
}
if (_kbhit()) // 检测玩家键盘是否有输入
playerMove(&moveDirection);
// 帧数限制
Sleep(200);
}
}
void test()
{
HideCursor();
srand((unsigned int)time(NULL)); // 获得时间戳以生成随机数
menu();
}
int main()
{
test();
return 0;
}
对于game.c
#include "game.h"
void gotoxy(int x, int y) // 光标移动到(x,y)的位置,可以让画面刷新
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);
}
void HideCursor() // 隐藏光标
{
CONSOLE_CURSOR_INFO cursor_info = { 1, 0 }; // 第二个值为0表示隐藏光标
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void init(int frame[HIGH][WIGHT])
{
// 初始化墙壁
for (int i = 0; i < HIGH; i++)
for (int j = 0; j < WIGHT; j++)
frame[i][j] = ((!i || i == HIGH - 1 || !j || j == WIGHT - 1) ? -1 : 0);
// 初始化蛇身蛇头
for (int i = 1; i <= 4; i++)
frame[HIGH / 2][WIGHT / 2 - i] = i;
// 生成食物
fruitGenerate(frame);
}
void display(int frame[HIGH][WIGHT])
{
for (int i = 0; i < HIGH; i++)
{
for (int j = 0; j < WIGHT; j++)
{
if (frame[i][j] == 0) // 打印空白
printf(" ");
else if (frame[i][j] == -1) // 打印墙壁
printf("#");
else if (frame[i][j] == 1) // 打印蛇头
printf("@");
else if (frame[i][j] > 1) // 打印蛇身
printf("O");
else if (frame[i][j] == -2) // 打印食物
printf("F");
}
printf("\n");
}
}
void fruitGenerate(int frame[HIGH][WIGHT])
{
while (1)
{
int y = rand() % (HIGH - 2) + 1;
int x = rand() % (WIGHT - 2) + 1;
if (frame[y][x] == 0)
{
frame[y][x] = -2;
break;
}
}
}
int snakeAutomaticMove(int frame[HIGH][WIGHT], int moveDirection) // 蛇自动移动
{
// 存储蛇头位置
int headX = 0;
int headY = 0;
// 存储蛇尾位置
int tailX = 0;
int tailY = 0;
int max = 0;
// 查找
for (int i = 1; i < HIGH - 1; i++)
{
for (int j = 1; j < WIGHT - 1; j++)
{
// 第一步:蛇头蛇身+1
frame[i][j] > 0 ? frame[i][j]++ : 0;
// 第二步:
// 记录蛇头
if (frame[i][j] == 2)
{
headX = j;
headY = i;
}
// 记录蛇尾
if (frame[i][j] > max)
{
max = frame[i][j];
tailX = j;
tailY = i;
}
}
}
// 第三步:
// 存储新蛇头
int newHeadY = 0;
int newHeadX = 0;
switch (moveDirection)
{
case 1: // 上
newHeadY = headY - 1;
newHeadX = headX;
break;
case 2: // 下
newHeadY = headY + 1;
newHeadX = headX;
break;
case 3: // 左
newHeadY = headY;
newHeadX = headX - 1;
break;
case 4: // 右
newHeadY = headY;
newHeadX = headX + 1;
break;
}
// 检测游戏状态并返回
return detectGameState(frame, newHeadY, newHeadX, tailY, tailX);
}
int detectGameState(int frame[HIGH][WIGHT], int newHeadY, int newHeadX, int tailY, int tailX)
{
// 当蛇吃到食物不用去掉旧蛇尾
if (frame[newHeadY][newHeadX] == -2)
{
fruitGenerate(frame); // 重新生成果实
}
else // 去掉旧蛇尾
frame[tailY][tailX] = 0;
// 吃到自己 或 撞墙
if (frame[newHeadY][newHeadX] > 0 || frame[newHeadY][newHeadX] == -1)
return 0;
else // 放置新蛇头
frame[newHeadY][newHeadX] = 1;
return 1;
}
void playerMove(int* moveDirection)
{
char input = _getch();
// 确定移动方向 且 禁止反方向移动
if (input == 'w' && *moveDirection != 2) // 上
*moveDirection = 1;
else if (input == 's' && *moveDirection != 1) // 下
*moveDirection = 2;
else if (input == 'a' && *moveDirection != 4) // 左
*moveDirection = 3;
else if (input == 'd' && *moveDirection != 3) // 右
*moveDirection = 4;
}
游戏补充内容实现
这里只是补充了一些小功能,就直接放源码了。
对于game.c
#pragma
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#define HIGH 20
#define WIGHT 30
void game();
void HideCursor(); // 隐藏光标
void gotoxy(int x, int y); // 固定画面
void init(int frame[HIGH][WIGHT]); // 游戏初始化
void display(int frame[HIGH][WIGHT], int scores, int quickly, int length); // 画面展示
int snakeAutomaticMove(int frame[HIGH][WIGHT], int moveDirection, int* scores, int quickly, int* length); // 蛇自动移动
void playerMove(int* moveDirection, int* quickly, int* stop); // 玩家操作
void fruitGenerate(int frame[HIGH][WIGHT]); // 生成果实
int detectGameState(int frame[HIGH][WIGHT], int newHeadY, int newHeadX, int tailY, int tailX, int* scores, int quickly, int* length); // 检测游戏状态
对于test.c
#include "game.h"
void explain()
{
printf("********** 操作说明 **********\n");
printf("* 移动键(小写) 上:w 下:s *\n");
printf("* 左:a 右:d *\n");
printf("* 空格:加速开关 *\n");
printf("* 加速吃果实分数为2,反之为1 *\n");
printf("* 小写字母j:暂停开关 *\n");
printf("********** 操作说明 **********\n");
printf("------------------------------\n");
printf("空格返回\n");
while (_getch() != ' ')
Sleep(10);
system("cls");
}
void menu()
{
int inputY = 0;
char arr[3][13] = { "开始游戏", "操作说明", "结束游戏" };
while (1)
{
gotoxy(0, 0);
printf("**********************\n");
if (inputY == 0)
printf("*****\033[41m %10s \033[0m*****\n", &arr[0][0]);
else
printf("***** %-11s*****\n", &arr[0][0]);
if (inputY == 1)
printf("*****\033[41m %10s \033[0m*****\n", &arr[1][0]);
else
printf("***** %-11s*****\n", &arr[1][0]);
if (inputY == 2)
printf("*****\033[41m %10s \033[0m*****\n", &arr[2][0]);
else
printf("***** %-11s*****\n", &arr[2][0]);
printf("**********************\n");
printf("上:w 下:s\n");
printf("空格键确定\n");
char ch = _getch();
switch (ch)
{
case 'w':
inputY = (inputY - 1 + 3) % 3;
break;
case 's':
inputY = (inputY + 1) % 3;
break;
case ' ':
if (inputY == 0)
{
system("cls");
game();
}
else if (inputY == 1)
{
system("cls");
explain();
}
else if (inputY == 2)
return;
}
Sleep(10);
}
}
void game()
{
// 开始移动方向为右
int moveDirection = 4;
// 检测游戏状态
int detect = 1;
// 获得的分数
int scores = 0;
// 是否为加速状态
int quickly = 0;
// 蛇的总长度
int length = 4;
// 游戏暂停
int stop = 0;
int frame[HIGH][WIGHT] = { 0 };
init(frame);
while (1)
{
gotoxy(0, 0);
detect = snakeAutomaticMove(frame, moveDirection, &scores, quickly, &length);
display(frame, scores, quickly, length);
if (!detect)
{
printf("游戏结束,按空格返回\n");
while (_getch() != ' ')
Sleep(10);
system("cls");
break;
}
if (_kbhit()) // 检测玩家键盘是否有输入
playerMove(&moveDirection, &quickly, &stop);
if (stop)
{
while (_getch() != 'j')
Sleep(10);
stop = 0;
}
// 帧数限制
quickly ? Sleep(100) : Sleep(200);
}
}
void test()
{
HideCursor();
srand((unsigned int)time(NULL)); // 获得时间戳以生成随机数
menu();
}
int main()
{
test();
return 0;
}
对于game.c
#include "game.h"
void gotoxy(int x, int y) // 光标移动到(x,y)的位置,可以让画面刷新
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);
}
void HideCursor() // 隐藏光标
{
CONSOLE_CURSOR_INFO cursor_info = { 1, 0 }; // 第二个值为0表示隐藏光标
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void init(int frame[HIGH][WIGHT])
{
// 初始化墙壁
for (int i = 0; i < HIGH; i++)
for (int j = 0; j < WIGHT; j++)
frame[i][j] = ((!i || i == HIGH - 1 || !j || j == WIGHT - 1) ? -1 : 0);
// 初始化蛇身蛇头
for (int i = 1; i <= 4; i++)
frame[HIGH / 2][WIGHT / 2 - i] = i;
// 生成食物
fruitGenerate(frame);
}
void display(int frame[HIGH][WIGHT], int scores, int quickly, int length)
{
for (int i = 0; i < HIGH; i++)
{
for (int j = 0; j < WIGHT; j++)
{
if (frame[i][j] == 0) // 打印空白
printf(" ");
else if (frame[i][j] == -1) // 打印墙壁
printf("#");
else if (frame[i][j] == 1) // 打印蛇头
printf("%s", quickly ? "\033[31;1m@\033[0m" : "\033[34;1m@\033[0m");
else if (frame[i][j] > 1) // 打印蛇身
printf("%s", quickly ? "\033[31;1mO\033[0m" : "\033[34;1mO\033[0m");
else if (frame[i][j] == -2) // 打印食物
printf("\033[32;1mF\033[0m");
}
if (!i)
printf("***********************");
else if (i == 1)
printf("***** 分数为:%-4d*****", scores);
else if (i == 2)
printf("***********************");
else if (i == 3)
printf("** 是否为加速状态:%s **", quickly ? "\033[31;1m是\033[0m" : "\033[34;1m否\033[0m");
else if (i == 4)
printf("***********************");
else if (i == 5)
printf("***********************");
else if (i == 6)
printf("*** 蛇的总长度:%-4d ***", length);
else if (i == 7)
printf("***********************");
printf("\n");
}
}
int snakeAutomaticMove(int frame[HIGH][WIGHT], int moveDirection, int* scores, int quickly, int* length) // 蛇自动移动
{
// 存储蛇头位置
int headX = 0;
int headY = 0;
// 存储蛇尾位置
int tailX = 0;
int tailY = 0;
int max = 0;
for (int i = 1; i < HIGH - 1; i++)
{
for (int j = 1; j < WIGHT - 1; j++)
{
// 蛇头蛇身自增
frame[i][j] > 0 ? frame[i][j]++ : 0;
// 记录蛇头
if (frame[i][j] == 2)
{
headX = j;
headY = i;
}
// 记录蛇尾
if (frame[i][j] > max)
{
max = frame[i][j];
tailX = j;
tailY = i;
}
}
}
// 存储新蛇头
int newHeadY = 0;
int newHeadX = 0;
switch (moveDirection)
{
case 1:
newHeadY = headY - 1;
newHeadX = headX;
break;
case 2:
newHeadY = headY + 1;
newHeadX = headX;
break;
case 3:
newHeadY = headY;
newHeadX = headX - 1;
break;
case 4:
newHeadY = headY;
newHeadX = headX + 1;
break;
}
// 检测游戏状态并返回
return detectGameState(frame, newHeadY, newHeadX, tailY, tailX, scores, quickly, length);
}
void playerMove(int* moveDirection, int* quickly, int* stop)
{
char input = _getch();
// 确定移动方向 且 禁止反方向移动
if (input == 'w' && *moveDirection != 2) // 上0x48
*moveDirection = 1;
else if (input == 's' && *moveDirection != 1) // 下0x50
*moveDirection = 2;
else if (input == 'a' && *moveDirection != 4) // 左0x4b
*moveDirection = 3;
else if (input == 'd' && *moveDirection != 3) // 右0x4d
*moveDirection = 4;
else if (input == 'j') // 暂停
*stop = !(*stop);
else if (input == ' ') // 加速
*quickly = !(*quickly);
}
void fruitGenerate(int frame[HIGH][WIGHT])
{
while (1)
{
int y = rand() % (HIGH - 2) + 1;
int x = rand() % (WIGHT - 2) + 1;
if (frame[y][x] == 0)
{
frame[y][x] = -2;
break;
}
}
}
int detectGameState(int frame[HIGH][WIGHT], int newHeadY, int newHeadX, int tailY, int tailX, int* scores, int quickly, int* length)
{
// 当蛇吃到食物不用去掉旧蛇尾
if (frame[newHeadY][newHeadX] == -2)
{
quickly ? (*scores) += 2 : (*scores)++;
(*length)++;
fruitGenerate(frame);
}
else // 去掉旧蛇尾
frame[tailY][tailX] = 0;
// 吃到自己 或 撞墙
if (frame[newHeadY][newHeadX] > 0 || frame[newHeadY][newHeadX] == -1)
return 0;
else // 放置新蛇头
frame[newHeadY][newHeadX] = 1;
return 1;
}
结语
以上是便是全部内容,若文章有问题或游戏有bug,可以告诉我,我会及时补充。
谢谢阅读