一、代码解读
一个按钮来启动游戏的开始,开始以后LCD1602上显示当前的关卡和得分,当长到一定长度后会进入下一个关卡,每个关卡移动的速度不一样(越到后面速度越快,用到定时器)
有关蛇和食物里的属性都有很多,考虑使用结构体来存储:
结构体一定要初始化,有的编译器全局结构体可能会初始化0,但最好初始化一下。
struct Food
{
unsigned char x; // 食物的横坐标
unsigned char y; // 食物的纵坐标
}food; // 食物结构体
struct Snake
{
char x[SNAKE_Max_Long];
char y[SNAKE_Max_Long];
unsigned char Long; // 蛇的长度
unsigned char Life; // 蛇的生命
unsigned char Score; // 蛇的分数
unsigned char Level; // 蛇的等级
unsigned char Dir; // 蛇移动方向
}snake; // 蛇结构体
结构体初始化:
每次默认都从一个地方出生,而且方向都向右。
//****************初始化蛇的位置等***********************//
static void initSnake()
{
//********清除内存数据**********//
unsigned char i;
for(i=0; i<SNAKE_Max_Long; i++)
{
snake.x[i]=-1;
snake.y[i]=-1;
}
//********初始化蛇参数**********//
snake.Long=2; // 初始化蛇的长度为两节
snake.Life=1; //初始化蛇活着
if(snake.Level>1) //不是重新开始,而是新关卡
{
}
else
{
snake.Level = 1;
snake.Score = 0;
}
snake.Dir=right;
snake.x[1]=0;
snake.y[1]=2;
snake.x[0]=1;
snake.y[0]=2;
createFood();
}
食物随机产生:
static void createFood()
{
unsigned char i;
food.x = rand()%WIDTH;
food.y = rand()%LENGTH;
for(i=0; i<snake.Long; i++)
{
if(food.x==snake.x[i] && food.y==snake.y[i])
{
break;
}
}
//产生食物成功
if(i==snake.Long)
{
return;
}
//失败
else
{
createFood(); //重新产生
}
}
蛇运动坐标刷新:
到了一定时间才刷新,这个时间用定时器控制。
看到这个,是不是也想到了滚动字符,也可以这样做,当然也可以在数组里用%来解决。
static void runSnake()
{
unsigned char i;
// 蛇身体坐标移动,蛇头方向坐标逐渐向蛇尾方向移动
for(i=snake.Long; i>0; i--)
{
snake.y[i]=snake.y[i-1];
snake.x[i]=snake.x[i-1];
}
// 重新获得蛇的头部位置
switch(snake.Dir)
{
case up: snake.y[0]-=1; break;
case down: snake.y[0]+=1; break;
case left: snake.x[0]-=1; break;
case right: snake.x[0]+=1; break;
default: break;
}
// 蛇吃到食物
if(snake.x[0]==food.x && snake.y[0]==food.y)
{
snake.Long++;
snake.Score++;
createFood();
}
}
判定蛇死:
两种情况判定蛇死了。
// 限定蛇活动范围,超范围就dead
if((snake.x[0]>(WIDTH-1)) || (snake.x[0]<0) || (snake.y[0]>(LENGTH-1)) || (snake.y[0]<0))
{
snake.Life=0;
snake.Level=1;
speedLevel=25;
keyVal=right;
LcdShowOver();
}
// 蛇自杀检测
for(i=4; i<=snake.Long; i++)
{
if(snake.x[i-1]==snake.x[0] && snake.y[i-1]==snake.y[0])
{
snake.Life=0;
snake.Level=1;
speedLevel=25;
keyVal=right;
LcdShowOver();
}
}
在8*8点阵上显示:
void drawSnake()
{
unsigned char i=0;
for(i=0; i<8; i++) DispRAM[i]=0;
for(i=0; i<snake.Long; i++)
DispRAM[snake.y[i]] |= 1<<snake.x[i];
scanDisplay(DispRAM);
drawPoint(food.x, food.y);
}
二、Proteus图

三、演示
Proteus仿真贪吃蛇小游戏
本文详细解析了如何使用结构体和定时器实现贪吃蛇游戏,包括蛇和食物的属性管理、结构体初始化、食物随机生成、蛇的运动与死亡判断,以及在Proteus环境中进行的游戏演示。通过实例展示了如何在8x8点阵LCD上显示和使用定时器控制刷新频率。
7652

被折叠的 条评论
为什么被折叠?



