贪吃蛇课程设计Word格式.docx
- 文档编号:4095043
- 上传时间:2023-05-02
- 格式:DOCX
- 页数:38
- 大小:108.88KB
贪吃蛇课程设计Word格式.docx
《贪吃蛇课程设计Word格式.docx》由会员分享,可在线阅读,更多相关《贪吃蛇课程设计Word格式.docx(38页珍藏版)》请在冰点文库上搜索。
●大量使用寄存器,指令执行速度更快;
●大多数数据操作都在寄存器中完成;
●寻址方式灵活简单,执行效率高;
●指令长度固定;
●ARM处理器共有37个寄存器,被分为若干个组(BANK),这些寄存器包括:
●31个通用寄存器,包括程序计数器(PC指针),均为32位的寄存器。
●6个状态寄存器,用以标识CPU的工作状态及程序的运行状态,均为32位,目前只使用了其中的一部分。
●ARM处理器又有7种不同的处理器模式,在每一种处理器模式下均有一组相应的寄存器与之对应。
即在任意一种处理器模式下,可访问的寄存器包括15个通用寄存器(R0~R14)、一至二个状态寄存器和程序计数器。
在所有的寄存器中,有些是在7种处理器模式下共用的同一个物理寄存器,而有些寄存器则是在不同的处理器模式下有不同的物理寄存器。
●ARM微处理器的在较新的体系结构中支持两种指令集:
ARM指令集和Thumb指令集。
其中,ARM指令为32位的长度,Thumb指令为16位长度。
Thumb指令集为ARM指令集的功能子集,但与等价的ARM代码相比较,可节省30%~40%以上的存储空间。
二.功能描述
基本功能:
开始蛇向右方移动。
按键盘上定义的上下左右键,蛇改变游动的方向,可以上下左右游动。
蛇不能碰到图中的灰色栅栏,如碰到游戏结束。
若蛇碰到图中一粒豆子,则豆子被蛇吃掉,图中的豆子消失,蛇身变长。
最终所有的豆子都被吃掉,游戏结束。
增强要求:
(1)必须改进游戏的界面,增加显示相关的统计信息。
左边的显示区保持不变,右边动态显示积分和总时间统计信息,其中积分栏目显示当前已经吃下的豆子数目,总时间显示本局游戏从开始到现在经过的时间。
(2)优化主程序,注意CPU和内存的使用效率。
(3)考虑一个合理的得分算法,得分值应该取决于吃下去的豆子和游戏持续的时间。
(4)得分可以在发光二极管上显示出来。
三.基本原理
游戏开始后进入游戏界面.首先初始化蛇的坐标,食物的坐标.线程基本流程:
判断是否是暂停阶段,是否有有退出按键,游戏是否有结束,如果都没有就执行,如果游戏结束了就重新游戏或者退出。
开启键盘功能,实现通过方向键来控制蛇的移动方向;
开启数码管功能,实现蛇吃到食物后能够更新和显示分数;
利用变量,实现吃了6个食物后,游戏能够结束,并能通过增加蛇的移动速度来增加游戏的难度。
贪吃蛇游戏设计最主要在蛇移动的控制,在设计中用数组来存放蛇身的坐标,用数组boolbean00[3]、boolbean01[1]、boolbean10[1]、boolbean11[1]存放豆子,变量mscore记录得分,并利用数码管显示技术实时显示分数,考虑一个合理的得分算法,得分值应该取决于吃下去的豆子和游戏持续的时间。
四.系统总体设计
4.1相关初始化
1.堆栈大小,任务优先级定义
OS_STKMain_Stack[STACKSIZE*8]={0,};
//Main_Test_Task堆栈
voidMain_Task(void*Id);
//Main_Test_Task
#defineMain_Task_Prio12
OS_STKLed_Flash_Stack[STACKSIZE]={0,};
//LED闪烁任务堆栈
voidLed_Flash_Task(void*Id);
//LED闪烁任务
#defineLed_Flash_Prio60
OS_STKTransmit_Task_Stack[STACKSIZE*8]={0,};
//Transmit_Task堆栈
voidTransmit_Task(void*Id);
//Transmit_Task
#defineTransmit_Task_Prio20
2.任务的创建
OSTaskCreate(Main_Task,(void*)0,(OS_STK*)&
Main_Stack[STACKSIZE*8-1],Main_Task_Prio);
OSTaskCreate(Led_Flash_Task,(void*)0,(OS_STK*)&
Led_Flash_Stack[STACKSIZE-1],Led_Flash_Prio);
OSTaskCreate(Transmit_Task,(void*)0,(OS_STK*)&
Transmit_Task_Stack[STACKSIZE-1],Transmit_Task_Prio);
3.初始化蛇身
U8HeadPos[2];
U8EndPos[2];
4.初始化豆子
u8bean00[3][2]={{2,11},{18,13},{15,20}};
u8bean01[1][2]={{10,27}};
u8bean10[1][2]={{38,3}};
u8bean11[1][2]={{27,38}};
BOOLEANboolbean00[3]={TRUE,TRUE,TRUE};
BOOLEANboolbean01[1]={TRUE};
BOOLEANboolbean10[1]={TRUE};
BOOLEANboolbean11[1]={TRUE};
4.2任务设计
4.2.1任务设计要求
本设计需要创建三个任务,,任务一Main_Task和任务二Transmit_Task,任务三Led_Flash_Task,任务三为Led显示任务,这里不做详细解释。
只对任务一跟任务二详细说明。
在系统启动后,同时创建两个任务,任务一和任务二.任务一主要功能是等待键盘消息,有键盘消息的时候判断是什么键盘,并对相应的变量重新赋值.任务二主要功能是控制并在屏幕上显示蛇的移动,并完成对分数和其他相关参数的记录和显示.任务一为主任务,在创建任务的时候,赋给它的优先级别比任务二高,所以任务一优先运行,任务二处于就绪状态,因为任务一主要是等待键盘消息,在无键盘消息的时候,任务一被挂起,这时候任务二进入运行状态.
4.2.2流程图
1.程序流程图(不包括任务三)
图1程序流程图(不包括任务三)
2.任务一(主任务)流程图
图2任务一(主任务)流程图
3.任务二流程图
图3任务二流程图
五.硬件设计
由于本次课程设计在平台上做开发,所以几乎不会涉及到具体的硬件概要设计、详细设计、制作。
但对于所用到的驱动,应有所了解。
硬件不同,平台就不同,程序的效果也就不同。
六.软件设计
6.1移动功能的实现
移动功能的实现:
通过ChangePointCount记录改变次数,ChangePointPos[10][2]记录每次的坐标,没有移动改变的时候,用绘图函数画原先的图,有移动的时候,先画头部,再利用循环画中间,最后画尾部。
实现代码:
oldendpos[0]=EndPos[0];
//记录蛇的位置
oldendpos[1]=EndPos[1];
//判断snake头部的变化
switch(HeadDirect)
//根据所按键蛇头向上向下向左向右移动,由于使用switch语句,横纵坐标只能有一个发生变化,且一次只能向一个方向,所以蛇头向上向下向左向右移动。
{
case1:
HeadPos[0]=HeadPos[0]+m;
//蛇头横坐标移动m
break;
case2:
HeadPos[0]=HeadPos[0]-m;
case3:
HeadPos[1]=HeadPos[1]-m;
//蛇头纵坐标移动m
case4:
HeadPos[1]=HeadPos[1]+m;
}
//判断snake尾部的变化
if(ChangePointCount>
0)
{
if((abs(ChangePointPos[ChangePointCount-1][0]-EndPos[0])+abs(ChangePointPos[ChangePointCount-1][1]-EndPos[1]))==0)
DelChangePoint();
}
switch(EndDirect)
{
case1:
EndPos[0]=EndPos[0]+m;
//蛇尾横坐标移动m
break;
case2:
EndPos[0]=EndPos[0]-m;
case3:
EndPos[1]=EndPos[1]-m;
//蛇尾纵坐标移动m
case4:
EndPos[1]=EndPos[1]+m;
}
//绘制snake
//ClearScreen();
//Draw3DRect2(pdc,psnakeRect,RGB(0,0,0),RGB(0,0,0));
FillRect2(pdc,pbarRect1,GRAPH_MODE_NORMAL,RGB(0,255,255));
FillRect2(pdc,pbarRect2,GRAPH_MODE_NORMAL,RGB(0,255,255));
if(ChangePointCount==0)
draw_rect(HeadPos[0],HeadPos[1],EndPos[0],EndPos[1]);
else//不断调用可以动态显示移动过程
draw_rect(HeadPos[0],HeadPos[1],ChangePointPos[0][0],ChangePointPos[0][1]);
for(i=1;
i<
ChangePointCount;
i++)
{draw_rect(ChangePointPos[i-1][0],ChangePointPos[i-1][1],ChangePointPos[i][0],ChangePointPos[i][1];
draw_rect(ChangePointPos[i-1][0],ChangePointPos[i-1][1],EndPos[0],EndPos[1]);
OSTimeDly(200);
}
6.2判断吃否吃到豆子
判断蛇是否吃到食物的方法比较简单,只要判断蛇头的X,Y坐标是否同时和食物的坐标的X,Y一样.吃到食物后改变响应的游戏参数,这时候要让变量addcount加1,要注意根据此时蛇的运动方向来确定新蛇头的坐标.另外,要注意,蛇吃完食物后,要把变量boolbean00[i],bean01[0],bean10[0],bean11[0]赋值FALSE,食物产生子程序能够判断食物已经被蛇"
吃到"
了,要重新产生食物.
代码:
if(HeadPos[0]<
=20)
if(HeadPos[1]<
=20)
{
for(i=0;
i<
3;
i++)
if(boolbean00[i]==TRUE)
{
if((bean00[i][0]==HeadPos[0])&
&
(bean00[i][1]==HeadPos[1]))
{catch=TRUE;
boolbean00[i]=FALSE;
addcount=2;
number++;
score(number);
mscore=number*2-n*0.01+1;
scoresco(mscore);
key=mscore;
//得到按键值
Delay
(1);
ZLG7289_ENABLE();
//使zlg7289占有同步串口
WriteSDIO(ZLG7289_CMD_DATA0|0);
//数码管以方式0译码,第一个数码管亮
WriteSDIO(key%10);
//显示个位
//延时
if(key>
9)
{//键值大于9显示十位
WriteSDIO(ZLG7289_CMD_DATA0|1);
//发送十位数据
WriteSDIO((unsignedchar)(key/10));
Delay
(1);
WriteSDIO(ZLG7289_CMD_HIDE);
//使一、二两位数码管显示
WriteSDIO(3);
else
{//键值小于10不显示十位
//使个位数码管显示
WriteSDIO
(1);
ZLG7289_DISABLE();
//zlg7289放弃同步串口控制权
//shine();
return;
}
}
}
else
if(boolbean01[0]==TRUE)
if((bean01[0][0]==HeadPos[0])&
(bean01[0][1]==HeadPos[1]))
{
catch=TRUE;
boolbean01[0]=FALSE;
addcount=2;
number++;
else
if(boolbean10[0]==TRUE)
if((bean10[0][0]==HeadPos[0])&
(bean10[0][1]==HeadPos[1]))
boolbean10[0]=FALSE;
if(boolbean11[0]==TRUE)
if((bean11[0][0]==HeadPos[0])&
(bean11[0][1]==HeadPos[1]))
boolbean11[0]=FALSE;
}
6.3画豆子
画豆子时,通过判断豆子有没有被吃掉决定要不要画,如果已经被蛇吃掉,就不画,没有吃掉就画,通过数组的值是TRUE还是FALSE来判断。
数组的值为TRUE则画圆表示豆子,数组的值为FALSE则不画。
FillRect2(pdc,psnakeRect,GRAPH_MODE_NORMAL,RGB(100,255,0));
//清除主窗口的显示
for(i=0;
if(boolbean00[i]==TRUE)
Circle(pdc,20+5*bean00[i][0]-2,20+5*bean00[i][1]-2,2);
if(boolbean01[0]==TRUE)
Circle(pdc,20+5*bean01[0][0]-2,20+5*bean01[0][1]-2,2);
if(boolbean10[0]==TRUE)
Circle(pdc,20+5*bean10[0][0]-2,20+5*bean10[0][1]-2,2);
if(boolbean11[0]==TRUE)
Circle(pdc,20+5*bean11[0][0]-2,20+5*bean11[0][1]-2,2);
6.4声音的播放
voidSong()
{
INT8Uerr;
U32nbyte;
FILE*pfile;
charfilename[]="
1.wav"
;
//声音的源文件
rIISCON=0;
//disable;
rIISMOD=IISMOD_TX|IISMOD_16BIT|IISMOD_32FS|IISMOD_MCLK_384FS;
rIISFCON=IISFCON_TXDMA|IISFCON_TXFIFO;
rIISPSR=0x11;
rIISCON=IISCON_PRESCALE|IISCON_ENABLE;
Init_UDA1341();
pfile=OpenOSFile(filename,FILEMODE_READ);
if(!
pfile)
return;
ReadOSFile(pfile,(U8*)buffer,0x16*2);
//读取头文件信息
nbyte=ReadOSFile(pfile,(U8*)buffer,sizeof(buffer));
//读取波形数据
for(;
)
/******BDMA0Initialize******/
//forSource
rBDISRC0=(1<
<
30)+(1<
28)+(int)buffer;
//Halfword,inc,Buf
//fordes
rBDIDES0=(1<
30)+(3<
28)+((int)0x1d18010);
//M2IO,fix,IISFIF
//Size
//iis,reserve,done_int,notauto-reload/start,DMAenable,COUNT
rBDICNT0=(1<
26)+(3<
22)+(0<
21)+(0<
20)+(sizeof(buffer)&
(~0x3));
rBDICNT0|=(1<
20);
//开启
//EnableDMA
rBDCON0=0x0<
2;
//TxDMA
rIISCON|=IISCON_TXDMA;
}
6.5数码管的点亮
key=mscore;
Delay
(1);
ZLG7289_ENABLE();
WriteSDIO(ZLG7289_CMD_DATA0|0);
WriteSDIO(key%10);
if(key>
6.6判断游戏进程
判断蛇是否撞到边框的方法,只要比较蛇头的X,Y坐标是不是同时和边框的X,Y坐标一样,一样的话,即表明蛇撞到边框,游戏结束
inti=0;
//if((HeadPos[0]>
xmax)||(HeadPos[0]<
xmin)||(HeadPos[1]>
ymax)||(HeadPos[1]<
ymin))
//{
//gameover=TRUE;
//return;
//}
__asm
cmpHeadPos[0],xmax
bgtgameend
cmpHeadPos[0],xmin
bltgameend
cmpHeadPos[1],ymax
cmpHeadPos[1],ymin
bgegamecontinue
gameend:
movgameover,#1
gamecontinue:
time(n);
n++;
if(gameover==TRUE)r
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 贪吃蛇 课程设计 贪吃