现在用8x8LED点阵制做的贪吃蛇游戏在网上的源码已经多不胜数了,因为闲得蛋疼,也搞了搞,不过由于Me很懒,又穷,因此硬件就木有搞,只是用proteus仿真了一下。。。
源码工程及仿真在这:https://pan.baidu.com/s/1i5tyOtv
顺便也唠叨一下这个贪吃蛇的源码吧,有图有真相,上图
(注意:对于仿真文件运行后点阵无显示的问题,须要将74HC238元件更新替换掉)
画面简单清晰明了,perfect!
贪吃蛇游戏主要包含几个程式:画蛇、画食物、蛇行走、蛇吃食物、蛇长身体、蛇撞墙dead、蛇自杀dead。
简约流程:界面初始化(画蛇、画食物)---->蛇行走---->蛇吃食物---->蛇长身体---->刷新显示页面
Let’s see the program。
在initSnake()这个函数中主要就是对蛇的一些初始化(如游戏开始时蛇在什么位置呀等等)web
//****************初始化蛇、食物等***********************// 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)是真正地在点阵上画食物的点。svg
//********************刷新界面*******************// 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!函数