关于贪吃蛇我认为最难实现的部分是如何控制小蛇的移动,还有吃到食物后小蛇变长的问题。
这个图可以解释:
小蛇移动:
第一步用12345个数字记录小蛇的位置,然后使所有的小蛇位置数字加一。
第二步使小蛇的最大值位置处变为0,就相当于那个位置消失了。
第三步使最小值的上/下/左/右位置(根据按键判断)的元素变为1。
小蛇吃到食物后变长:
上面的第二步是使最大值变为0,我们可以试想一下 如果吃到食物,最大值就不变为0了,那么这不就相当于小蛇变长了吗?这时,我们只需要加一个if else判断是否吃到食物即可。
头文件以及全局变量
#include<stdio.h>
#include<conio.h>
#include<windows.h>
#define high 26
#define width 46
int num[high][width] = {0}; //边框
int movesnake; //小蛇移动
int food_x, food_y;//食物
int score;//计分
防闪屏
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 };
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
初始化界面
void startup() {
//边框初始化
for (int i = 0; i < high; i++) {
num[i][0] = -1;
num[i][width - 1] = -1;
}
for (int j = 0; j < width; j++) {
num[0][j] = -3;
num[high - 1][j] = -3;
}
//小蛇初始化
num[high / 2][width / 2] = 1;
for (int i = 1; i <= 4; i++) {
num[high / 2][width / 2 - i] = i + 1;
}
movesnake = 4;//初始化蛇的移动方向
HideCursor();
//初始化食物
food_x = rand() % (high - 5) + 2;
food_y = rand() % (width - 5) + 2;
num[food_x][food_y] = -2;
}
主界面显示
void show() {
gotoxy(0, 0);
Sleep(150);
int i, j;
for (i = 0; i < high; i++) {
for (j = 0; j < width; j++) {
if (num[i][j] == -1) {
printf("|");
}
else if (num[i][j] == -3) {
printf("_");
}
else if (num[i][j] == 0) {
printf(" ");
}
else if (num[i][j] == 1) {
printf("@");
}
else if (num[i][j] > 1) {
printf("o");
}
else if (num[i][j] == -2) {
printf("$");
}
}
printf("\n");
}
printf("得分为:%d\n",score);
}
后台操作
void MoveSnakePostion() {
int max = 0;
int snakeback_i=0, snakeback_j=0;//用于记录旧的蛇尾的位置
int snakefront_i=0, snakefront_j=0;//用于记录旧的蛇头位置
int newhead_i=0, newhead_j=0;//记录新蛇头位置
for (int i = 1; i < high - 1; i++) {
for(int j=1;j<width-1;j++)
if (num[i][j] > 0) {
//大于零的部分就是贪吃蛇
num[i][j]++;//蛇身全部加1
if (max < num[i][j]) {//取到蛇的最大值部分也就是蛇的尾部
max = num[i][j];
snakeback_i = i;//记录蛇尾
snakeback_j = j;
}
if (num[i][j] == 2) {//记录旧的蛇头
snakefront_i = i;
snakefront_j = j;
}
}
}
if (movesnake == 1)//向上
{
newhead_i = snakefront_i - 1;
newhead_j = snakefront_j;
}
if (movesnake == 2)//向下
{
newhead_i = snakefront_i + 1;
newhead_j = snakefront_j;
}
if (movesnake == 3)//向左
{
newhead_i = snakefront_i;
newhead_j = snakefront_j - 1;
}
if (movesnake == 4)//向右
{
newhead_i = snakefront_i;
newhead_j = snakefront_j + 1;
}
if (num[newhead_i][newhead_j] == -2)
{
//当小蛇碰到食物 蛇的尾部就不需要变为零就相当于长度加1了
num[food_x][food_y] = 0;//食物原始位置归零 产生新食物
food_x = rand() % (high - 5) + 2;
food_y = rand() % (width - 5) + 2;
num[food_x][food_y] = -2;
score++;
}
//当小蛇没吃到食物
else num[snakeback_i][snakeback_j] = 0;//蛇身最大值的元素也就是蛇尾蛇尾变为0,蛇身就相当于长度不变
if (num[newhead_i][newhead_j] > 0 || num[newhead_i][newhead_j] == -1 || num[newhead_i][newhead_j] == -3 ) {
printf("Game Over\n\n");
exit(0);
}
else num[newhead_i][newhead_j]= 1;
}
void back() {
MoveSnakePostion();
}
人机交互
void front(){
char input;
if (kbhit()) {
input = getch();
if (input == 'a')
movesnake = 3;
if (input == 's')
movesnake = 2;
if (input == 'w')
movesnake = 1;
if (input == 'd')
movesnake = 4;
}
}
主界面
int main() {
startup();
while (1) {
show();
front();
back();
}
}
实现: