基于 ARM 平台的贪吃蛇游戏设计
姓
学
名:张琛
号:S201502164
指导老师:李晓光
一、设计要求
在 LCD 屏上实现一个贪吃蛇的小游戏。
开始显示为初始界面,然后开始进行游戏。游戏开始出现 1 节的蛇,一个食
物,显示得分。当进入游戏后,蛇自动前行。通过按键上下左右来控制蛇前行的
方向,当蛇吃到食物后,得分加 1 分,蛇身体变长一节。当蛇在游行过程中撞到
墙壁或者自身则游戏结束。
二、设计思路
程序的大体思想是:采用一个二维数组(这里我采用的是 44*62 的整形数组)
作为贪吃蛇游戏的背景地图,数组的每个值代表地图上每个小矩形,而每个小矩
形连续组成贪吃蛇的蛇身,在程序初始化窗体时候调用这个函数,刷新出程序的
背景地图;程序贪吃蛇的蛇身用一个 Cpoint 类的一位连续数组,Cpoint 类是一
个结构体类型,结构体类型里包含着两个整形参数 x 和 y 代表的是屏幕窗体上
的某一个对应的点的坐标,我们在得知点的坐标的同时,就明确了对应二维数组
地图上的某个矩形区域的坐标值,这样用 Cpoint 类的一位数组我们可以存放蛇
身的每个节点的坐标,于此同时,我们在程序 snake 类里面设定蛇头和蛇尾的坐
标变量、蛇身长度的坐标变量。在定义 snake 类的同时,定义了一个私有变量
Direction 为蛇动态前进的方向,并同时给 Direction 赋值,根据 Direction 变量控
制蛇的移动。
接着,需要考虑游戏的可行过程。这里我们首先考虑到一个十分重要的问题,
就是蛇遇到食物(这里我们用一个小矩形表示蛇的食物)同时,将食物吃掉并且动
态自身增加一节,这里我是这样想的:首先实现的是食物的随机出现,在某个食
物被吃掉的同时,我们要立即产生出下一个食物的坐标,我们用到的是一个随机
函数产生出下一个食物的坐标,但是这个坐标必须在背景范围内,且每次随机产
生的食物坐标不能出现在当前蛇身上。当蛇头坐标的下一个前进方向的坐标和食
物坐标相等时,可以将食物坐标改变成当前蛇头坐标,并且蛇尾坐标不变,蛇身
长度增加一个单位,这样就动态的现实出来蛇吃食物自身增加一个的效果。
最后考虑游戏结束问题。就是蛇在身条件下会死亡或胜利,即蛇遇到地图周
围的墙和遇到自己的身体蛇会死亡,而长度超过 50 即获得胜利。于此同时记录
下当前玩家所得的分数。
三、设计流程图
初始游戏界面任务:
按键查询任务:
LCD 显示初始界面
Key1
按下?
进入游戏界面
延时等待
游戏过程:
初始化
清屏、画出游戏的矩形墙壁、食物
判断蛇下一步的游行方向
根据确定的游行方向来计算
蛇的下一个位置坐标
N
N
判 断 是 否 吃 到 食
物?
Y
蛇身长度加一节
分数加 1 分
按着新蛇的坐标画蛇
蛇 撞 墙 或 者 自
身?
Y
游戏结束
延时
四、模块功能及核心代码
(1)主函数以及初始化:
void main ()
{
//打开扩展指令
uint16 i = 0;
SYS_Init();
initial();
w_cd(0x38,0);
init_dds();
output(100);
ADCSEED = ADConvert( 1 );
IRQEN = XIRQ0_BIT;
Write_CH452_comd( CH452_SYSON2W );//
LCD_clr();//清屏
Lcd_Clear(0);
welcome();
w_cd(0x01,0);
DELAY(10);
Lcd_Clear(0);
DrawBoard();//画界面
GamePlay();//玩游戏
GameOver();//游戏结束
}
(2)游戏选择界面:
void welcome()
{
display(1, 3, 4, "欢迎来到");
display(2, 3, 3, "贪吃蛇");
display(3, 3, 4, "K1 键开始");
display(4, 3, 4, "K2 键结束");
while(1)
{
if(Key_state==KEY1)
{
Key_state=KEY3;
break;
}
if(Key_state==KEY2)
{
LCD_clr();//清屏
Lcd_Clear(0);
display(2, 3, 4, "退出游戏");
Key_state=KEY3;
}
}
}
(3)子程序画围墙:
void DrawBoard(void)
{
unsigned char n;
for(n=0;n<15;n++)
{
Lcd_Rectangle(3*n,0,3*n+2,2,1);
Lcd_Rectangle(3*n,60,3*n+2,62,1);
}
for(n=0;n<20;n++)
{
Lcd_Rectangle(0,3*n,2,3*n+2,1);
Lcd_Rectangle(42,3*n,44,3*n+2,1);
}
disp_bmp() ;//送入 lcd 显示刷新
display(1,4,4,"贪吃蛇");
display(2,4,3,"得分:");
display(4,4,3,"张琛");
}
(4)游戏过程:
void GamePlay(void)
{
unsigned int i;
uint8 key_save;
InitRandom(ADCSEED); //随机数种子暂且先写个固定值 512
display(3,4,5,"S201502164");
PrintScore();
PrintLevel();
allsnake[0].x=10;
allsnake[0].y=10;
lengths+=1;
Lcd_PutPixel(allsnake[0].x,allsnake[0].y,1);
disp_bmp();
CreatSign();
disp_bmp();
while(1)
{
if(lengths<101)
{
//吃豆的过程
//判断豆是否在蛇头左边,并且往左运动
if(((allsnake[0].x-1)==allsnake[100].x)&&(allsnake[0].y==allsnake[100].y)&&(Key
_state==KEY5))
{
++lengths;
++Score;
for(i=0;i
disp_bmp();
PrintScore();
}
//判断豆是否在蛇头下边,并且往下运动
if((allsnake[0].x==allsnake[100].x)&&((allsnake[0].y+1)==allsnake[100].y)&&
(Key_state==KEY4))
{
++lengths;
++Score;
for(i=0;i