您的位置:首页 > 理论基础 > 数据结构算法

51单片机的8x8点阵贪吃蛇

2016-08-06 18:16 363 查看

51单片机的8x8点阵贪吃蛇

如今用8x8LED点阵制作的贪吃蛇游戏在网上的源码已经多不胜数了,由于闲得蛋疼,也搞了搞,不过因为Me很懒,又穷,所以硬件就木有搞,只是用proteus仿真了一下。。。

源码工程及仿真在这:https://pan.baidu.com/s/1i5tyOtv

顺便也唠叨一下这个贪吃蛇的源码吧,有图有真相,上图



画面简单清晰明了,perfect!

贪吃蛇游戏主要包含几个程式:画蛇、画食物、蛇行走、蛇吃食物、蛇长身体、蛇撞墙dead、蛇自杀
b2e8
dead。

简约流程:界面初始化(画蛇、画食物)—->蛇行走—->蛇吃食物—->蛇长身体—->刷新显示页面

Let’s see the program。

在initSnake()这个函数中主要就是对蛇的一些初始化(如游戏开始时蛇在什么位置呀等等)

//****************初始化蛇、食物等***********************//
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;   // 默认蛇的长度为2段
snake.Life=1;   // 蛇的生命
snake.Dir=right;
snake.x[1]=0;   // 蛇开始时的坐标位置[0]是蛇头位置
snake.y[1]=2;
snake.x[0]=1;
snake.y[0]=2;
createFood();   // 创建食物
}


接下来就是一条行走的贪吃蛇的关键了,runSnake()函数主要是为蛇行走时坐标位置改变而做的一些处理,第一个for的作用就是·······举例吧:假如我的蛇开始时是这样的[1][0],[0]是蛇头,那么当我向右移动1格的时候,此时[1]是不是就要到[0]的位置了,而[0]则要到一个新的位置(也就是在下面的switch中重新获得的蛇头位置)。当蛇头的位置和食物的位置吻合时,也就是说吃到食物了,此时蛇的长度增长,食物也需要重新创建了。另外提一提在createFood()函数中只用了rand()来产生随机数而rand()函数产生的是一个伪随机数(每次执行同一个程序,调用rand得到的随机数序列是固定的(不是真正的“随机”,所以我们每次开始仿真是都会发现食物的位置都是和上次仿真时一样的),如果想得到真正的随机数,网上有些源码的做法就是使用定时器,调用srand(定时器计数值)设置随机数种子,从而产生随机数,不过在这里我并没有使用。

//****************蛇行走、吃食物*******************//
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++;    // 长身体
createFood();    // 只是创建食物的坐标位置
}
}


Last,提一提这个刷新函数drawSnake(),for循环是将同一行的所有坐标点整合成一个8位的数(一行就相当于一个8位数值的二进制数,如初始化时蛇在第2行(0~7)显示的是00000011这样的一个8位数),从而可以在点阵上显示,点阵的显示是低位在前,从左到右坐标是01234567,scanDisplay(DispRAM)是将整合后的点真正地显示在点阵上,drawPoint(food.x, food.y)是真正地在点阵上画食物的点。

//********************刷新界面*******************//
static 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);   // 食物有了坐标就可以画点了
}


Fine,还有一些其他的函数可以查看源码,应该来说是相对比较容易理解的。

The end,Thanks!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息