




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、基于c /os系统、arm9硬件平台的贪吃蛇游戏设计 摘要程序核心思想:游戏开始后进入游戏界面。首先初始化蛇的坐标,食物的坐标。线程基本流程:判断是否是暂停阶段,是否有有退出按键,游戏是否有结束,如果都没有就执行,如果游戏结束了就重新游戏或者退出。设计要求;1、 能够通过方向键来控制蛇的移动方向;2、 蛇吃到食物后能够重新出现食物;并且能够更新和显示分数;3、 游戏开始的时候能通过手动进行游戏级别的调整;4、 每吃到5个食物后,游戏能够自动进入下一关,并能通过增加蛇的移动速度来增加游戏的难度;5、 游戏开始的时候能够手动对游戏级别进行调整;开发平台信息一、 c /os操作系统 c/os 和c/
2、os-ii 是专门为计算机的嵌入式应用设计的, 绝大部分代码是用c语言编写的。cpu 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的cpu 上。 c /os-ii 中最多可以支持64 个任务,分别对应优先级063,其中0 为最高优先级。63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个,每个任务都有不同的优先级,用户在创建任务的时候定义该任务的优先级。uc/os操作系统中每个任务可以有5种状态:休眠态、就绪态、运行态、等待或挂起状态、中断态,在任一个时候,任务的状态一定是这5种状态之
3、一。任务在等待消息、邮箱或者信号量等事件的到来的时候会进入挂起状态,当任务接到消息以后,则处于就绪状态。二、试验箱基本硬件信息1)cpu:s3c44b0x,arm7tdmi,工作在60mhz2)bios:2m,nor flash3)内存:8m sdram4)海量存储器:16m,nandflash5)键盘:17 键数字小键盘6)显示器:320240 16 级灰度的lcd(可选256 彩色lcd),四线电阻式触摸屏7)usb 接口:1.1 标准8)串行口:两个,最高波特率115200kb9)网络接口:10m 以太网10)can 接口:125kb,250kb,500kb,1mb11)调试接口:jta
4、g,14 针,20 针12)电机:直流电机(有刷),步进电机(带1/64 减速器)13)a/d:8 路10 位,满量程2.5v,已用前4 路14)d/a:10 位,满量程4.096v15)led:8 个,共阴极16)音频输出:44.1khz17)fpga(可选):acex 1k 系列,扩展输出100i/o,与s3c44b0x 外部总线直接相连18)扩展口:2 个二、开发集成环境arm sdt 2.5 集成开发环境arm sdt 2.5 集成开发环境(arm project manager)是arm公司(为方便用户在arm芯片上进行应用软件开发而推出的一整套集成开发工具。arm sdt可在win
5、dows95、98、nt以及solaris 2.5/2.6、hp-ux 10上运行,支持最高到arm9(含arm9)的所有arm处理器芯片的开发,包括strongarm。 arm sdt包括一套完整的应用软件开发工具: 1、*armcc arm的c编译器,具有优化功能,兼容于ansi c。 2、*tcc thumb的c编译器,同样具有优化功能,兼容于ansi c。 3、*armasm 支持arm和thumb的汇编器。 4、*armlink arm连接器,连接一个和多个目标文件,最终生成elf格式的可执行映像文件。 5、*armsd arm和thumb的符号调试器。详细设计一、属性解释贪吃蛇游戏
6、设计最主要在于蛇移动的控制,在设计中分别用两组一维数组snake .u16 x100和snake .u16 x100来分别0存放蛇身的坐标,x100代表横坐标,y100代表纵坐标。蛇的宽度设置为10个像素点。变量direction为移动方向, foodx,foody为食物的坐标。function.stop为判定是否是要结束退出游戏,function.restar用来在游戏结束后重新开始游戏。1000/snake.level为蛇的移动速度(在程序中用1000/snake.level作为每次循环的延迟时间),当snake.level的记录的等级越高的话,蛇的移动速度会越快(因为延迟时间越小),难度
7、越高。snake.life用来判定游戏是否结束,snake.life=1代表蛇已死,游戏结束。游戏的其他相关变量还有snake.node,用来记录蛇的节数;snake.score用来记录游戏得分;snake.level用来记录游戏的等级。二、相关初始化过程: 1、堆栈大小定义、任务优先级定义:os_stk main_stackstacksize*8=0, ;void main_task(void *id);#define main_task_prio 12os_stk control_stackstacksize*8=0, ;void control(void *id);#define con
8、trol_prio 15 2、任务的创建:ostaskcreate(main_task, (void *)0, (os_stk *)&main_stackstacksize-1, main_task_prio); ostaskcreate(control,(void *)0, (os_stk *)&control_stackstacksize*8-1, control_prio);3、初始化画笔宽度:setpenwidth(pdc,10);/ 初始化画笔宽度为10个像素点4、初始化蛇的节数:snake.node=5; /游戏开始时蛇有5节5、初始蛇尾巴的坐标:snake.x0=10; snak
9、e.y0=10;初始化蛇各节的坐标:for(i=0;i=snake.node-1;i+) snake.xi+1=snake.xi+10; snake.yi+1=snake.yi; 6、蛇相关参数的初始化:初始化移动方向为向右:snake.direction=6;7、游戏相关参数的初始化:初始化分数: snake.score=0; 初始化等级:snake.level=1;三、程序流程: 本设计需要创建两个任务,任务流程和任务状态切换如下图。具体的任务流程和任务所要完成的功能如下:在系统启动后,同时创建两个任务,任务一和任务二。任务一主要功能是等待键盘消息,有键盘消息的时候判断是什么键盘,并对相应
10、的变量重新赋值。任务二主要功能是控制并在屏幕上显示蛇的移动,并完成对分数、游戏等级、和其他相关参数的记录和显示。任务一为主任务,在创建任务的时候,赋给它的优先级别比任务二高,所以任务一优先运行,任务二处于就绪状态,因为任务一主要是等待键盘消息,在无键盘消息的时候,任务一被挂起,这时候任务二进入运行状态。1、程序主流程图:是否有键盘消息任务一挂起任务一,任务二就绪任务二挂起任务一运行任务二运行否是2、主任务流程图:主要功能是等待键盘消息,有键盘消息的时候判断是什么键盘,并对相应的变量重新赋值。等待键盘消息是否有键盘按下判断是哪个按键否8如果蛇现在的方向是左或者右就把方向改成向上2如果蛇现在的方向
11、是左或者右就把方向改成向下4如果蛇现在的方向是上或者下就把方向改成左6如果蛇现在的方向是上或者下就把方向改成右*发出退出游戏的信息发出重新开始游戏的信息/+对游戏的等级加1(只在游戏开始前有效)-对游戏的等级减1(只在游戏开始前有效)/n车确定等级选择,开始游戏是3、任务二流程图:主要功能是控制并在屏幕上显示蛇的移动,并完成对分数、游戏等级、和其他相关参数的记录和显示。初始化游戏是否结束是否调用食物产生程序根据direction变量移动蛇是否吃到食物否是蛇的节数加1分数加1加快蛇的移动速度是否要产生食物否是是否有返回按键显示结束画面否四、具体功能实现:1、移动功能的实现:这部分功能是游戏的主体
12、,实现蛇移动的方式是首先擦除蛇尾,擦除的方发是用白色的画笔覆盖画上蛇尾,蛇尾就变成白色底色不可见,然后从蛇尾开始,依次将蛇每一的坐标给下一节。例如刚开始蛇是5节,这时候依次把第2四节的坐标给第1节;把第3节(即蛇头)的坐标给第2节;把第4四节的坐标给第3节;把第4节(即蛇头)的坐标给第3节;把第5节(即蛇头)的坐标给第4节。擦除蛇尾和转移坐标这两个顺序不能颠倒。这时候蛇头的坐标和第4节的坐标是一样的,这时候需要判断变量snake.direction的值,根据snake.direction的值补画上蛇头。首先,擦除蛇尾setpencolor(pdc,0xffffffff); moveto (pd
13、c, snake.x0,snake.y0); lineto (pdc,snake. x0,snake.y0); 然后,蛇的每个环节坐标给下一节;for (i=0;i=0;i-) if(snake.xi=snake.xsnake.node&snake.yi=snake.ysnake.node) snake.life=1; break; else continue; (2)蛇头撞到游戏界面边框 判断蛇是否撞到边框的方法,只要比较蛇头的x、y坐标是不是同时和边框的x、y坐标一样,一样的话,即表明蛇撞到边框,游戏结束。例如:本设计中以(10, 45)为坐标原点的情况下,只要保证蛇头的x坐标在0620之
14、间(像素点为单位),蛇头y坐标在0415之间(像素点为单位),即表示蛇没有撞到边框。 if (snake.xsnake.node=0|snake.xsnake.node=620|snake.ysnake.node=0|nake.ysnake.node=415) snake.life=1; 5、监听键盘动作:任务通过等待消息而处于挂起状态,当任务接到消息以后,则处于就绪状态,然后开始判断所接受到的这个消息是不是需要处理,如果是执行相应的处理函数,最后,删除所接收到的消息,继续挂起等待下一条消息。void main_task (void *id) /main_test_task u8 xiaoxi
15、; posmsg pmsg=0; for( ; ; ) pmsg=waitmessage(0); switch(pmsg-message) case osm_key: xiaoxi=onkey(pmsg-wparam,pmsg-lparam); if(xiaoxi= default: break; ostimedly(200); deletemessage(pmsg) ; u8 onkey ( int nkey,int fnkey ) switch(nkey) case return default: return false; 程序下载与调试1、把程序下载到试验箱中:(1)执行菜单proje
16、ct | make 对工程进行编译连接。在出现的错误/警告窗口中选择某错误/警告信息,ads 会自动打开相应源文件并用箭头指向出错的文本行。如果某个源文件被修改,重新编译时ads 会自动同步各文件的日期信息。(2)在ads 中执行菜单project | debug 启动ads1.2 的调试工具axd。(3)在axd 中执行菜单options | configure target 对axd 进行设置。选择adp 即远程调试,点configure 按钮进一步设置具体参数。(4)点select 按钮选择远程连接为arm ethernet driver,点configure 按钮输入仿真器的ip 地址
17、。如果用户使用的是并行口仿真器,请输入127.0.0.1 即可。(5)等待程序装载完毕以后,通过execute | go 菜单以及execute | stop(或者工具栏中的相应按钮)运行或暂停程序。程序暂停后在窗口中将显示出程序暂停的位置。(6)通过execute | step 菜单(或者工具栏中的相应按钮)可以单步运行程序。也可以使用 step in、step out 菜单命令进入或者跳出函数的调用。run to cursor 命令运行到光标位置。(7)程序停止后可以通过processor views | sources 菜单查看源文件,并可在适当位置按f9 设置端点。(8)使用在proc
18、essor view 菜单下的registers、variables 和memory 命令可以查看工作寄存器或者内存变量。读者可以逐一地尝试,为以后调试程序打下基础。注意:在进行调试时在ads 中必须选择当前工程的debug 版本,如果选择release 版本则无法正常调试程序。但在调试通过后就必须选择release 版本进行编译连接并将生产的system.bin 文件复制到开发板的flash 中。将开发板上的flash 激活并使windows 认其为一个2、运行结果与不足: 本程序能够完成设计目的的所有基本要求;(1)能够通过方向键来控制蛇的移动方向;(2)蛇吃到食物后能够重新出现食物;并且
19、能够更新和显示分数;(3)每吃到5个食物后,游戏能够自动进入下一关,并能通过增加蛇的移动速度来增加游戏的难度;(4)能够通过按键随便退出游戏,并能通过按键重新进入游戏;未能实现的功能;本程序设计时预想在游戏开始前能够停留在游戏界别设置画面,并能通过手动进行游戏级别的调整,“+”按键用来增加游戏级别,“-”按键用来减少游戏级别,并能在屏幕上显示游戏灌输,等到有确认信息,游戏才开始。但是此部功能没有实现,实验的时候程序能够进入级别调整画面,并等待用户对游戏等级进行调整,但是“+”、“-”按键和确认按键无效,没办法对游戏级别进行调整。由于调试时间有限,最后删掉次部分功能。不足之处:(1)方向按键按下
20、后,要有一定的延迟蛇才能对按键作出反应,这个延迟不是很明显,但是刚开始游戏的时候,总感觉不能刚好控制蛇吃到食物,需要稍微提早一些时间按下按键才能让蛇延目标方向移动。这个不足的原理是因为每次按键按下,要等到下一次循环,蛇才能响应方向改变,而蛇控制的程序中每次循环中用到了比较多的循环语句,判断,跳转,每次程序循环所需要的时间比较长,所以感觉按键有一点延迟,但是这个延迟非常的小,并不明显。解决方法:要优化蛇控制程序,简化程序过程。(2)蛇的移动范围和游戏界面有些不一致,例如蛇会稍稍超出游戏界面的边框。这是因为蛇移动时候所用的坐标原点和画游戏界面所用的坐标原点不一样,在判断蛇是否超出边框时要注意计算在
21、新坐标原点下,边框的位置,以便准确判断出蛇是否超出游戏界面。这个问题仅仅是画面上有点缺陷,不影响贪吃蛇的功能。解决方法:要准确计算出游戏边框相对坐标原点的距离(像素点)。总结:想要写出好的程序,需要我们有扎实的基础,这样遇到一些基本算法的时候可能就会游刃有余了。在编程是我们要有丰富的想象力。不要拘泥于固定的思维方式,遇到问题的时候要多想几种解决问题的方案,试试别人从没想过的方法。丰富的想象力是建立在丰富的知识的基础上,所以我们要通过多的途径来帮助自己建立较丰富的知识结构。 在编程时我们会碰到了很多的困难,这就需要我们多与别人交流。三人行必有我师,也许在一次和别人不经意的谈话中,就可以迸出灵感的
22、火花。在编程的过程中我们也看到了有良好的编程风格是十分重要的,至少在时间效率上就体现了这一点。养成良好的习惯,代码的缩进编排,变量的命名规则要始终保持一致,这些都是提高我们编程的注意点。 还有在变成中最能体现简单的原则。所以我们要思考讨论简单的程序,这样简单的方法更容易被人理解,更容易实现,也更容易维护。遇到问题时要优先考虑最简单的方案,只有简单方案不能满足要求时再考虑复杂的方案。附录程序:*#include./ucos-ii/includes.h /* uc/os interface */#include ./ucos-ii/add/osaddition.h#include ./ucos-i
23、i/add/ustring.h#include ./inc/drivers.h#include ./inc/sys/lib.h#include ./src/gui/gui.h#include #include #pragma import(_use_no_semihosting_swi) / ensure no functions that use semihosting */任务定义os_stk main_stackstacksize*8=0, ; /main_test_task堆栈void main_task(void *id); /main_test_task#define main_t
24、ask_prio 12os_stk control_stackstacksize*8=0, ; /test_test_task堆栈void control(void *id); /control_task#define control_prio 15/*已经定义的os任务*#define sys_task_prio1#define touch_screen_task_prio9#define main_task_prio 12#define key_scan_task_prio 58#define lcd_fresh_prio 59#define led_flash_prio 60* main
25、 function. *int main(void)armtargetinit(); / do target (uhal based arm system) initialisation /osinit(); / needed by uc/os-ii /osinituart();initosfile();#if use_minigui=0initosmessage();initoslist();initosdc();initosctrl();loadfont();#endifloadsystemparam();lcd_printf(create task on ucos-ii.n);ostas
26、kcreate(main_task, (void *)0, (os_stk *)&main_stackstacksize-1, main_task_prio); ostaskcreate(control,(void *)0, (os_stk *)&control_stackstacksize*8-1, control_prio); osaddtask_init(1); lcd_printf(starting ucos-ii.n);lcd_printf(entering graph mode.n);lcd_changemode(dspgramode);osstart(); / start the
27、 os / return 0;*struct food u16 foodx;/用来记录食物的坐标 u16 foody; food;struct snake /定义蛇结构体 u16 x100; u16 y100; u16 node; /蛇的节数*/ u16 direction;/蛇移动方向*/ u16 life; u16 level; u16 unicode_level1; u16 score; u16 unicode_score1; snake;struct function /用来结束和重新开始 u8 stop; /暂停 u8 restar; /重新开始 u8 situation; func
28、tion;/函数声明*u8 onkey(int nkey, int fnkey);void control(void*id);/主函数*void main_task(void *id) /main_test_task u8 xiaoxi; posmsg pmsg=0;for(;) pmsg=waitmessage(0); switch(pmsg-message) case osm_key: xiaoxi=onkey(pmsg-wparam,pmsg-lparam); if(xiaoxi=8&snake.direction=4) snake.direction=8; else if(xiaoxi
29、=2&snake.direction=4) snake.direction=2; else if(xiaoxi=4&snake.direction=8) snake.direction=4; else if(xiaoxi=6&snake.direction=8) snake.direction=6; else if(xiaoxi=8&snake.direction=6) snake.direction=8; else if(xiaoxi=2&snake.direction=6) snake.direction=2; else if(xiaoxi=4&snake.direction=2) sna
30、ke.direction=4; else if(xiaoxi=6&snake.direction=2) snake.direction=6; else if (xiaoxi=9) function.stop=1; else if (xiaoxi=7) if(function.stop=1) function.restar=1; else if(xiaoxi=5) if(snake.level!=9& function.situation=0) snake.level+; else if(xiaoxi=3) if(snake.level!=0& function.situation=0) sna
31、ke.level-; else if(xiaoxi=1) function.situation=1 ; default: break; ostimedly(200); deletemessage(pmsg) ; u8 onkey(int nkey,int fnkey) switch(nkey) case 2: return 2; case 4: return 4; case 6: return 6; case 8: return 8; case * : return 9; case /: return 7; case +: return 5; case -: return 3; case n:
32、 return 1; default: return false;/蛇控制*void control(void *id) int a; /用来接受随即函数产生的数值 int b; /用来接受随即函数产生的数值 int eye; /用来表示要不要产生随即食物坐标 int c; int i; int oldx,oldy;/保存原来坐标系位置 pdc pdc; /定义绘图设备上下文结构 u16 shijian=s,n,a,k,e,0; u16 llevel =l,e,v,e,l,:,0; u16 mark =s,c,o,r,c,e,:,0; u16 gameover=g,a,m,e, ,o,v,e,
33、r,0; clearscreen();/清屏 pdc=createdc();/创建绘图设备上下文 * for( ; ; ) clearscreen(); function.situation=0; setdraworg(pdc, 0, 0,&oldx,&oldy);/设置绘图原点为屏幕左边中部 for( ; ; ) if (function.situation=0) textout(pdc, lcdwidth/2,200,llevel,true,fontsize_middle); int2unicode(snake.level,snake.unicode_level);textout(pdc,lcdwidth/2,240,snake.unicode_level,true,fontsize_middle); else break; * snake.score=0; snake.level=1; eye=0; levelchange: clearscreen(); setpenwidth(pdc,4); moveto(pdc, 10, 10); lineto(pdc, 630, 10 ); moveto(pdc, 630, 10 ); lineto(pdc, 630, 460); moveto(pdc, 630, 460); lineto(pdc, 10, 460);
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 医药股份面试题及答案
- 绿色生态停车场产权交易及维护服务合同
- 2026版《全品高考》选考复习方案生物22 15.1自由组合定律 含答案
- 厨房物资采购方案
- 企业商业秘密保护课件
- 库房整修改造方案
- 校内竞聘面试题及答案
- 世界地图考试题及答案
- 运城联考试题及答案
- 阳台吊篮补修方案
- 学堂在线 大学生国家安全教育 期末考试答案
- 碳化硅培训课件
- 2025年三门峡卢氏县事业单位(联考)招聘81人笔试模拟试题及答案
- 2025年公需科目考试试卷(含答案)
- 暑假教研活动方案
- 2025年广西中考物理试题及答案
- 车辆事故警示教育
- 2024年北京市海淀区招聘社区工作者考试真题
- 2025年广东中考数学试题(含答案详解)
- 2025年 四川省港航投资集团有限责任公司招聘考试笔试试卷附答案
- 干眼的药物治疗讲课件
评论
0/150
提交评论