1.设计思路
总的来说,贪吃蛇这个小游戏涉及到的东西不多,但是对逻辑思维是比较吃基本功的。
贪吃蛇,
显示给我们看的有三部分:蛇、食物、地图边界
。
我们可以用一个二维数组来标记这些部分:
例如这里我创建了一个 5*10 的二维数组,
其中 -1 表食物, 1 表蛇头,2、3、4、5表蛇身,0表示空地。
如果我们想要蛇移动起来,只需要将 蛇尾置0 ,其余部分+1 就行了。
另外需要说明的是,我们使用 a s d w 来控制方向,这四个方向对应的整数分别是:3、2、1、0。
2.具体流程
3.源文件(主函数)main.c
#include "head.h"
int main()
{
int map[SIZE][SIZE] = { 0 };//定义二维数组
int len = 0;//定义长度
int state = 0;//定义游戏状态
int direc = 0;//定义方向
Init_map(map, &len, &direc);//初始化地图
while (1)
{
direc = get_direc(direc);//键盘读入方向
state = move(map, direc, &len);//蛇的移动,在函数内部判断蛇头状态并返回值
if (state == 0)//返回0表游戏结束
break;
else//继续游戏
print(map);//打印
Sleep(100);
}
return 0;
}
4.头文件head.h
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <math.h>
#define SIZE 19
void Init_map(int map[SIZE][SIZE], int* len, int* direc);
int get_direc(int direc);
int move(int map[SIZE][SIZE], int direc, int* len);
void print(int map[SIZE][SIZE]);
5.源文件(函数内部)func.c
void Init_map(int map[SIZE][SIZE], int* len, int* direc)
{
*len = 3;//初始化长度
*direc = 2;//初始化方向
map[5][5] = -1;//初始化食物
//初始化蛇身
map[3][3] = 3;
map[4][3] = 2;
map[5][3] = 1;//初始化蛇头
}
int get_direc(int direc)
{
int tmp = -1;//定义一个用来接收键盘值的变量
if (_kbhit())//如果键盘被敲击,kbhit()返回一个非0值
{
switch (_getch())//从键盘读入
{
case 'W':case 'w':tmp = 0; break;
case 'D':case 'd':tmp = 1; break;
case 'S':case 's':tmp = 2; break;
case 'A':case 'a':tmp = 3; break;
}
//读入的键盘只能是 w、d、s、a,并且蛇不能掉头
if (tmp != -1 && abs(direc - tmp) != 2)//abs函数是求绝对值
direc = tmp;
}
return direc;
}
int move(int map[SIZE][SIZE], int direc, int* len)
{
int i = 0;
int j = 0;
//定义蛇头位置
int head_x = 0;
int head_y = 0;
//循环遍历数组
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
if (map[i][j] == *len)//如果是蛇尾
map[i][j] = 0;
if (map[i][j] > 1)//如果是蛇身
map[i][j] += 1;
if (map[i][j] == 1)//如果是蛇头
{
map[i][j] += 1;
//此时蛇头+1了,已经没有蛇头了,现在就要找到一个新的蛇头
//
//找到原蛇头的原位置
head_x = i;
head_y = j;
//找到蛇头移动后的位置
switch (direc)
{
case 0:head_x = i - 1; head_y = j; break;
case 1:head_x = i; head_y = j + 1; break;
case 2:head_x = i + 1; head_y = j; break;
case 3:head_x = i; head_y = j - 1; break;
}
}
}
}
if (map[head_x][head_y] == -1)//如过蛇头位置是食物
{
*len = *len + 1;//吃掉食物,长度+1
map[head_x][head_y] = 1;//吃掉食物,食物变成蛇头
//重新生成食物
while (1)
{
i = rand() % SIZE;
j = rand() % SIZE;
if (map[i][j] == 0)
{
map[i][j] = -1;
break;
}
}
}
//如果蛇头碰到自己或墙
else if (map[head_x][head_y] > 0 || head_x < 0 || head_x == SIZE || head_y < 0 || head_y == SIZE)
return 0;//返回0
else
map[head_x][head_y] = 1;//没碰到食物、墙壁、自己
return 1;//没碰到食物、墙壁、自己
}
void print(int map[SIZE][SIZE])
{
//打印边框、食物、蛇用的符号根据自己的喜好来,是自由不受限制的
system("cls");
int i = 0;
int j = 0;
//打印上边框
for (i = 0; i <= SIZE; i++)
{
if (i == 0)
printf("┏");
else if (i == SIZE)
printf(" ┓");
else
printf(" ━");
}
printf("\n");
//打印左、右边框,打印蛇头、蛇身、食物
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
if (j == 0)
printf("┃ ");
else if (map[i][j] == -1)
printf("★");
else if (map[i][j] > 0)
printf("○");
else if (map[i][j] == 1)
printf("●");
else
printf(" ");
if (j == SIZE - 1)
printf("┃");
}
printf("\n");
}
//打印下边框
for (i = 0; i <= SIZE; i++)
{
if (i == 0)
printf("┗");
else if (i == SIZE)
printf(" ┛");
else
printf(" ━");
}
printf("\n");
}
6.结束语
可以看到,我们除去无用的换行、注释部分,
真正的代码不到200行
。这只是一个有基本功能的贪吃蛇小游戏。希望大家在这个版本的基础上添加一些花里胡哨的功能。
最后附上游戏效果截图。
版权声明:本文为weixin_59913110原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。