基于ARM9的贪吃蛇游戏

上传人:s**** 文档编号:82684746 上传时间:2022-04-29 格式:DOC 页数:27 大小:124KB
返回 下载 相关 举报
基于ARM9的贪吃蛇游戏_第1页
第1页 / 共27页
基于ARM9的贪吃蛇游戏_第2页
第2页 / 共27页
基于ARM9的贪吃蛇游戏_第3页
第3页 / 共27页
点击查看更多>>
资源描述
. . . 基于ARM9的贪吃蛇游戏摘要本课程设计是使用我们学习过的嵌入式系统的有关知识,在ARM9嵌入式硬件开发平台和C/OS-II的软件开发框架下,实现一个还有AD转换,按键,LCD等硬件功能的实时多任务的简单贪吃蛇的设计。文中首先C/OSII系统和ARM9进行了介绍,然后对设计要求进行分析,给出了系统总体上设计,并对各个功能模块进行了介绍,紧接着给出了 系统软件设计,最后介绍了系统的调试方法和测试结果。关键词:C/OS ARM9 嵌入式 贪吃蛇一 开发环境简介1、C /OS-II操作系统C/OS-II是一种可移植的,可植入ROM的,可裁剪的,抢占式的,实时多任务操作系统核。它被广泛应用于微处理器、微控制器和数字信号处理器。uC/OS-II只是一个实时操作系统核,它仅仅包含了任务调度,任务管理,时间管理,存管理和任务间的通信和同步等基本功能。没有提供输入输出管理,文件系统,网络等额外的服务。但由于uC/OS-II良好的可扩展性和源码开放,这些非必须的功能完全可以由用户自己根据需要分别实现。 uC/OS-II目标是实现一个基于优先级调度的抢占式的实时核,并在这个核之上提供最基本的系统服务,如信号量,消息队列,存管理,中断管理等C/OS-II 是专门为计算机的嵌入式应用设计的,绝大部分代码是用C语言编写的。CPU 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU 上。C /OS-II 中最多可以支持64个任务,分别对应优先级063,其中0 为最高优先级。63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个,每个任务都有不同的优先级,用户在创建任务的时候定义该任务的优先级。C/OS操作系统中每个任务可以有5种状态:休眠态、就绪态、运行态、等待或挂起状态、中断态,在任一个时候,任务的状态一定是这5种状态之一。任务在等待消息、或者信号量等事件的到来的时候会进入挂起状态,当任务接到消息以后,则处于就绪状态。uC/OS-II的时间管理是通过定时中断来实现的,该定时中断一般为10毫秒或100毫秒发生一次,时间频率取决于用户对硬件系统的定时器编程来实现。中断发生的时间间隔是固定不变的,该中断也成为一个时钟节拍。 uC/OS-II要求用户在定时中断的服务程序中,调用系统提供的与时钟节拍相关的系统函数,例如中断级的任务切换函数,系统时间函数。在ANSI C中是使用malloc和free两个函数来动态分配和释放存。但在嵌入式实时系统中,多次这样的操作会导致存碎片,且由于存管理算法的原因,malloc和free的执行时间也是不确定。 uC/OS-II中把连续的大块存按分区管理。每个分区中包含整数个大小一样的存块,但不同分区之间的存块大小可以不同。用户需要动态分配存时,系统选择一个适当的分区,按块来分配存。释放存时将该块放回它以前所属的分区,这样能有效解决碎片问题,同时执行时间也是固定的。对一个多任务的操作系统来说,任务间的通信和同步是必不可少的。uC/OS-II中提供了4种同步对象,分别是信号量,消息队列和事件。所有这些同步对象都有创建,等待,发送,查询的接口用于实现进程间的通信和同步。uC/OS-II 采用的是可剥夺型实时多任务核。可剥夺型的实时核在任何时候都运行就绪了的最高优先级的任务。 uC/os-II的任务调度是完全基于任务优先级的抢占式调度,也就是最高优先级的任务一旦处于就绪状态,则立即抢占正在运行的低优先级任务的处理器资源。为了简化系统设计,uC/OS-II规定所有任务的优先级不同,因为任务的优先级也同时唯一标志了该任务本身。随着信息化技术的发展和数字化产品的普与,以计算机技术、芯片技术和软件技术为核心的嵌入式系统再度成为当前研究和应用的热点。 对功能、可靠性、成本、体积和功耗严格要求的嵌入式系统一般由嵌入式微处理器、外围硬件设备、嵌入式操作系统以与用户的应用程序等四个部分组成,其中嵌入式微处理器和嵌入式操作系统分别是其硬件和软件的核心。 ARM处理器由于其具有小体积、低功耗、低成本、高性能等特点,广泛应用在16/32位嵌入式RISC解决方案中,几乎占有嵌入式微处理器市场分额的75% ,本文选定三星公司生产的一款基于ARM920T核的高性能低功耗SOC芯片S3C2410作为移植方案的硬件平台。市场上主流的嵌入式实时操作系统有Vxworks、pSos、WinCE、Linux等,基于实时性、成本以与开发难度方面的考虑,我们选择uC/OS II开放源代码的嵌入式实时操作系统。采用基于ARM9的S3C2410嵌入式微处理器,可以使系统具备高性能的运算能力的同时便于与各种外设连接扩展,简化了硬件设计,维持小型化的同时降低了系统成本。uC/OS II作为一个源代码公开的操作系统,在具体应用中稳定可靠,并且支持uIP TCP/IP协议栈、ucGUI等,可扩展性强,功能强大。本系统采ARM9+uC/OS II开发设计,具有精度高、运行稳定、实时性好、抗干扰能力强、性价比高的特点,可以在各种工业场合中广泛应用,达到了设计的初衷。2、试验箱基本硬件信息1S3C2410-S Core 小板:采用S3C2410X 处理器,64M NANDFLASH 64RAM。2Double 100M EtherNet网卡:均由AX88796 构成,采用现有电路但分配不同地址。34 HOST / 1 DEVICE USB 接口:主USB 口扩展为4个,由AT43301 构成USB HUB,其中电源管理用MIC2525。USB 从口保持处理器本身的1个。43 UART/IrDA:保持2个RS232 串口,增加1个RS485 串口,1个IrDA 收发器,均从处理器的UART2 引出。5168Pin EXPORT:有一个168Pin 扩展卡插槽,并去掉已经被主板上各模块占用的资源。网卡部分还在局部总线上,其余电路包括168Pin 扩展槽都在外部总线。6LCD:兼容多种LCD,可采用5 寸256 色屏或8 寸16bit 真彩屏,同时预留一个24bit 接口。可以支持板外8bit 或24bit 屏。7TouchScr:采用ADS7843,预备了直接用2410 部ADC 构成的转换电路接口8AUDIO:采用UDA1341,具有放音、录音等功能。9PS2 KEYPAD:使用ATMEGA8 单片机控制2个PS2 接口和板载17键小键盘。两个PS2 可接PC 键盘和鼠标。10LED:使用ZLG7290 只驱动8 只小数码管。同时可作IIC 总线实验。11POWER SUPPLY、RESET、RTC 等必须资源。12ADC:板载3个电位器和选择跳线,同时在板上设模拟电压输入专用接口。13IDE/CF 卡插座:支持2.5 英尺的笔记本硬盘读写和IDE 模式下的CF 卡读写。14PCMCIA 和SD 卡插座:由EPM3128A100 CPLD 实现。15IC 卡插座。由ATMEGA8 单片机控制。16DC/STEP 电机。步进电机采用74HC573 扩展IO,软件形成时序来控制。同时剩余IO 可以控制CAN 等电路,以节省CPU 的GPIO 资源。17CAN BUS:设置1个CAN 口,采用MCP2510 和TJA1050。18Double DA:设置两个DAC 端口,采用MAX504 接SPI 总线。19GPRS/GPS 扩展板不做在主板上,单独设计扩展板。注意GPS 的RS232 需要增加MAX3232芯片来转换为TTL 才能引到168Pin 插座上。3 、ADS1.2集成开发环境ADS1.2 ADS是ARM公司的集成开发环境,他的功能非常强大。ADS包括了四个模块分别是:SIMULATOR;C 编译器;实时调试器;应用函数库。ADS1.2提供完整的WINDOWS界面开发环境。C编译器效率极高,支持c 以与c+,使工程师可以很方便的使用C语言进行开发。提供软件模拟仿真功能,使没有Emulators的学习者也能够熟悉ARM的指令系统。配合FFT-ICE使用,ADS1.2提供强大的实时调试跟踪功能,片运行情况尽在掌握。ADS1.2需要硬件支持才能发挥强大功能。目前支持的硬件调试器有Multi-ICE以与兼容Multi-ICE的调试工具如FFT-ICE。ADS由命令行开发工具,ARM实时库,GUI开发环境(Code Warrior和AXD),适用程序和支持软件组成。有了这些部件,用户就可以为ARM系列的RISC处理器编写和调试自己的开发应用程序了。二 系统设计要求 贪吃蛇游戏是一款经典的小游戏,它的原型是1976年,Gremlin平台推出了一款经典街机游戏Blockade。真正走红的是该游戏随诺基亚手机走向世界。本课程设计有关贪吃蛇的功能描述:1、可以通过嵌入式平台的键盘控制游戏,键盘中起作用的是方向键(2,4,6,8)和回车键,方向键控制蛇的上下左右运动,回车键控制游戏的继续和暂停。2、贪吃蛇由若干连续黄色方块构成,程序中随机出现一些“食物”(用蓝色的方块表示),贪吃蛇通过吃“食物”增加自身的长度并增加相应的分值。3、游戏分三个关口,第一关没有障碍物,第二关有2个障碍物,第三关有四个障碍物。4、贪吃蛇撞到矩形边界,障碍物或者自己身体的一部分,游戏即结束,重新开始。5、为了增加难度,加入AD转换器用于控制蛇的运动速度,这也是本设计的创新点。6、贪吃蛇每吃一个食物分数会增加,屏幕上显示得分和游戏所用时间。三 系统总体设计本设计需要创建两个任务,系统结构框图如图3-1所示,任务状态切换如图3-2所示。具体的任务流程和任务所要完成的功能如下:在系统启动后,同时创建两个任务,任务一main_task和任务二snake_task。任务一主要功能是等待键盘消息,有键盘消息的时候判断是什么键盘,并对相应的变量重新赋值。任务二主要功能是控制并在屏幕上显示蛇的移动和速度,并完系统初始化任务一任务二等待键盘消息控制蛇移动AD采样LCD显示图3-1 系统结构框图任务一,任务二就绪是否有键盘消息任务一挂起任务二运行任务二挂起任务一运行图3-2 任务切换框图8等待键盘消息是否有按键按下识别是哪个按键是否如果蛇现在的方向是左或者右就把方向改成向上如果蛇现在的方向是左或者右就把方向改成向下如果蛇现在的方向是上或者下就把方向改成向左如果蛇现在的方向是上或者下就把方向改成向右如果游戏是运行的则改为竞争,静止就改为运行246/n图3-3 系统主任务流程框图成对分数,游戏等级和其他相关参数的记录和显示。任务一为主任务,在创建任务的时候,赋给它的优先级别比任务二高,所以任务一优先运行,任务二处于就绪状态,因为任务一主要是等待键盘消息,在无键盘消息的时候,任务一被挂起,这时候任务二进入运行状态。1、任务一程序流程框图如图3-3所示, 该任务完成对键盘消息的接收,识别,并改变相应变量2、任务二流程图:如图3-4所示,主要功能是控制蛇的速度并在屏幕上显示蛇的移动,并完成对分数、游戏等级、和游戏用时的记录和显示。四 系统具体功能的实现1初始化初始化包括了硬件初始化和软件初始化。硬件初始化主要有AD转换器的初始化,LCD的初始化,串口初始化,ARM目标板的初始化等,软件初始化包括了系统初始化,游戏初始化。系统初始化包括了任务的建立,信号量的创建,变量的创建,系统文件初始化,初始化绘图设备上下文,系统实时时钟的初始化和函数的声明等,游戏的初始化,包括了有关参数属性的初始化化和游戏界面的初始化。硬件初始化:#define ADCCON_FLAG(0x115)#define ADCCON_ENABLE_START_BYREAD(0x11)#define rADCCON(*(volatile unsigned *)0x58000000)#define rADCDAT0(*(volatile unsigned *)0x5800000C)#define PRSCVL (496)#define ADCCON_ENABLE_START (0x1)#define STDBM (0x02)初始化蛇增加长度计数器=0长度计数器减1,蛇长加1是否撞到障碍物或者边框?撞到食物游戏结束重新开始开始更新蛇头和蛇尾加分进入下一关下一关初始化蛇长计数器赋值更新LCD显示调用等待函数,根据等级和AD转换 确定等待时间图3-4 游戏任务流程图#define PRSCEN (0x1Type=TP_SkHead; xNode-isBlock=1; HeadNode=xNode; UpdateNextNode(xNode,Left); xNode-PreDir=Left;/Snake Body xNode=&WorldArrayW_YSize/2W_XSize/2; xNode-Type=TP_SkBody; xNode-isBlock=1; UpdateNextNode(xNode,Left); xNode-PreDir=Left; /Snake Tail xNode=&WorldArrayW_YSize/2W_XSize/2+1; xNode-Type=TP_SkTail; xNode-isBlock=1; TailNode=xNode; UpdateNextNode(xNode,Left); xNode-PreDir=Left; RandCake();2 判断蛇是否吃到食物判断蛇是否吃到食物的方法比较简单,只要判断蛇头的属性是否和下一个节点的属性一样。吃到食物后改变响应的游戏参数,并要让蛇的节数多三节,这时候要让变量lenadd加3, 并且还要对蛇补画上一节,本设计采用补上蛇头的方法,要注意根据此时蛇的运动方向来确定新蛇头的坐标。,以后食物产生子程序能够判断食物已经被蛇“吃到”了,要重新产生食物。 if(HeadNode-Type=TP_Cake) score+; if(score=5) flag1=1; else if (score=10) flag2=1; LenToAdd+=CakeLength; RandCake(); 3 判断游戏是否结束(1) 蛇头撞到蛇身判断蛇是否撞到蛇身的方法可以从蛇头开始依次开始判断蛇头的属性是否和下一个方块的属性一样,一样的话即表明蛇撞到蛇身了,此时游戏结束。(2)蛇头撞到游戏界面边框判断蛇是否撞到边框的方法,只要比较蛇头的属性是不是同时边框的属性一样,一样的话,即表明蛇撞到边框,游戏结束。If(HeadNode-isBlock) nRet=1;/Hit a Block goto SnakeStep_End; 4 蛇移动功能这部分功能是游戏的主体,实现蛇移动的方式是首先擦除蛇尾,擦除的方发是改变蛇尾的属性,通过调用绘图上下文设备,蛇尾就变成白色底色不可见,然后从蛇尾开始,依次改变下一个节点的属性。例如刚开始蛇是5节,这时候依次把第2四节的属性给第1节;把第3节(即蛇头)的属性给第2节;把第4四节的属性给第3节;把第4节(即蛇头)的属性给第3节;把第5节(即蛇头)的属性给第4节。擦除蛇尾和转移坐标这两个顺序不能颠倒。这时候蛇头的属性和第4节的属性是一样的,这时候需要判断蛇的方向变量的值,根据蛇的方向变量的值补画上蛇头。If (LenToAdd != 0) LenToAdd-; else TailNode-Type=TP_Space; TailNode-IsBlock=0; DrawPoint(TailNode); /old tail TailNode=TailNode-Next; TailNode-Type=TP_SkTail; DrawPoint(TailNode); /new tail HeadNode-Type=TP_SkBody; /old head DrawPoint(HeadNode); HeadNode-Next-PreDir=HeadNode-Dir; /save predir HeadNode=HeadNode-Next; /new head5 食物的产生食物的产生主要要注意食物产生之前,我们必须要判断画面上面是已经存在食物,如有已经存在食物了,就不再产生食物,如果食物被蛇吃到了,那就要重新画上食物。本设计是通过在每次吃完食物后调用随机产生食物函数,另外还要保证食物不能超出蛇的活动界面,并要保证食物能被蛇吃到,所以需要指定食物坐标的围,被通过舍去食物坐标个位的方法保证食物坐标是整十,这样就能被蛇吃到。本设计用一个矩形方框来代表食物,所以通过上面介绍的方法产生食物坐标后,对应在该坐标的位置画上一个矩形方框。void RandCake (void) /Get a new rand cake position INT32U x,y; While(1) X=rand()%W_XSize; Y=rand()%W_YSize; if(!WorldArrayyx.isBlock) break; CakeNode=&WorldArrayyx; CakeNode-Type=TP_Cake; DrawPoint(CakeNode);5、监听键盘动作:任务通过等待消息而处于挂起状态,当任务接到消息以后,则处于就绪状态,然后开始判断所接受到的这个消息是不是需要处理,如果是执行相应的处理函数,最后,删除所接收到的消息,继续挂起等待下一条消息。void Main_Task(void *Id) POSMSG pMsg=0;/定义消息结构ClearScreen ();/清屏 WorldSem=OSSemCreate(1); GameRun=OSSemCreate(1);Pdc=CreateDC();SetLCDUpdata(pdc,FALSE);/消息循环For(;) pMsg = WaitMessage ( 0);/等待消息switch(pMsg-Message)case OSM_KEY:/键盘消息 onKey(pMsg-WParam,pMsg-LParam); break; DeleteMessage ( pMsg );/删除消息DestoryDC(pdc);6 AD控制蛇速度在每次蛇前进一步后,通过刷新LCD屏幕来显示画面和相关参数,紧接着占用系统信号量,占用的时间是同过当前游戏的关口和调用AD采样函数来确定的额,游戏关口越高,蛇的前进速度越快,AD采样值越小,蛇的前进速度越快。OSTimeDly(GetSpeed(gamelevel);INT32S GetSpeed(U8 level) int ADData; U16 lastData; ADData=GetADresult(0); lastData=ADData*3.3*50/1023;if (level=1) return 300+lastData;else if (level=2) return 200+lastData; else return 100+lastData; 四 程序下载与调试1、把程序下载到试验箱中:(1)执行菜单Project | 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 地址。如果用户使用的是并行口仿真器,请输入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)使用在Processor View 菜单下的Registers、Variables 和Memory 命令可以查看工作寄存器或者存变量。读者可以逐一地尝试,为以后调试程序打下基础。注意:在进行调试时在ADS 中必须选择当前工程的Debug 版本,如果选择Release 版本则无常调试程序。但在调试通过后就必须选择Release 版本进行编译连接并将生产的system.bin 文件复制到开发板的Flash 中。将开发板上的Flash 激活并使Windows 认其为一个2、运行结果与不足:本程序能够完成设计目的的所有基本要求;(1)能够通过方向键来控制蛇的移动方向;(2)蛇吃到食物后能够重新出现食物;并且能够更新和显示分数,时间;(3)每吃到5个食物后,游戏能够自动进入下一关,并能通过增加蛇的移动速度来增加游戏的难度;(4)能够通过实验箱上的旋钮控制蛇的运行速度。未能实现的功能;本程序设计时预想在游戏开始前能够停留在游戏界别设置画面,并能通过手动进行游戏级别的调整,“+”按键用来增加游戏级别,“-”按键用来减少游戏级别,并能在屏幕上显示游戏灌输,等到有确认信息,游戏才开始。但是此部功能没有实现,实验的时候程序能够进入级别调整画面,并等待用户对游戏等级进行调整,但是“+”、“-”按键和确认按键无效,没办法对游戏级别进行调整。由于调试时间有限,最后删掉次部分功能。不足之处:(1)方向按键按下后,要有一定的延迟蛇才能对按键作出反应,这个延迟不是很明显,但是刚开始游戏的时候,总感觉不能刚好控制蛇吃到食物,需要稍微提早一些时间按下按键才能让蛇延目标方向移动。这个不足的原理是因为每次按键按下,要等到下一次循环,蛇才能响应方向改变,而蛇控制的程序中每次循环中用到了比较多的循环语句,判断,跳转,每次程序循环所需要的时间比较长,所以感觉按键有一点延迟,但是这个延迟非常的小,并不明显。解决方法:要优化蛇控制程序,简化程序过程。(2)蛇的移动围和游戏界面有些不一致,例如蛇会稍稍超出游戏界面的边框。这是因为蛇移动时候所用的坐标原点和画游戏界面所用的坐标原点不一样,在判断蛇是否超出边框时要注意计算在新坐标原点下,边框的位置,以便准确判断出蛇是否超出游戏界面。这个问题仅仅是画面上有点缺陷,不影响贪吃蛇的功能。解决方法:要准确计算出游戏边框相对坐标原点的距离(像素点)。五 总结想要写出好的程序,需要我们有扎实的基础,这样遇到一些基本算法的时候可能就会游刃有余了。在编程是我们要有丰富的想象力。不要拘泥于固定的思维方式,遇到问题的时候要多想几种解决问题的方案,试试别人从没想过的方法。丰富的想象力是建立在丰富的知识的基础上,所以我们要通过多的途径来帮助自己建立较丰富的知识结构。在编程时我们会碰到了很多的困难,这就需要我们多与别人交流。三人行必有我师,也许在一次和别人不经意的谈话中,就可以迸出灵感的火花。在编程的过程中我们也看到了有良好的编程风格是十分重要的,至少在时间效率上就体现了这一点。养成良好的习惯,代码的缩进编排,变量的命名规则要始终保持一致,这些都是提高我们编程的注意点。还有在变成中最能体现简单的原则。所以我们要思考讨论简单的程序,这样简单的方法更容易被人理解,更容易实现,也更容易维护。遇到问题时要优先考虑最简单的方案,只有简单方案不能满足要求时再考虑复杂的方案。附录程序代码:/*Copyright (c) 2004-2007 threewaterup-tech., All rights reserved.by threewter2004.5.12*/* #说明: C main 函数,ucos-ii初始化等定义- Bug - TODO list -修正-2004-5-12创建*/#include./ucos-ii/includes.h /* uC/OS interface */#include ./ucos-ii/add/osaddition.h#include ./inc/drivers.h#include ./ucos-ii/add/Osmessage.h#include ./inc/sys/lib.h#include ./src/gui/gui.h#include ./ucos-ii/add/rtc.h#include #include #include #include #pragma import(_use_no_semihosting_swi) / ensure no functions that use semihosting /*任务定义*/OS_STK Main_Stack STACKSIZE = 0, ; /Main_Test_Task堆栈void Main_Task(void *Id); /Main_Test_Task#define Main_Task_Prio 12OS_STK Snake_Stack STACKSIZE = 0, ; /snake_Test_Task堆栈void Snake_Task(void *Id); /snake_Test_Task#define Snake_Task_Prio 16/*已经定义的OS任务*#define SYS_Task_Prio1 / 系统任务#define Touch_Screen_Task_Prio9 / 触摸屏任务#define Main_Task_Prio 12 / 主任务#define Snake Stack_Prio 16 / 游戏任务#define Key_Scan_Task_Prio 58 / 按键扫描任务#define Lcd_Fresh_prio 59 / 液晶屏刷新任务#define Led_Flash_Prio 60 / 数码管刷新任务*/*事件定义*/OS_EVENT *WorldSem; /定义全局信号量OS_EVENT *GameRun;/定义游戏运行信号量#define W_XSize 32 / 游戏屏幕的宽度#define W_YSize 21 / 游戏屏幕的高度#define CakeLength 3 / 定义每次吃个食物蛇长增加3/defs.struct Pt /定义坐标变量 INT8U x; INT8U y;enum WN_Type /定义枚举变量的方块类型 TP_Space, / 空白类型 TP_Block, / 块状类型 TP_Cake, /食物类型 TP_SkBody, /蛇的躯体 TP_SkHead, / 蛇的头 TP_SkTail / 蛇的尾;enum Direction Up=0,Down=1,Left=2,Right=3;/ 定义方向的枚举型变量typedef struct WorldNode /定义节点类型结构变量 BOOLEAN isBlock; / 布尔型变量 enum WN_Type Type; /方块类型的变量 enum Direction Dir; /方向类型的变量 enum Direction PreDir; / 方向类型的变量 struct Pt pos; /坐标类型的变量 struct WorldNode* Next; / 定义节点类型的指针WorldNode; /functions. 函数声明void UpdateNextNode (struct WorldNode* xNode, enum Direction Dir);/更新下一节点函数void DrawPoint (struct WorldNode* xNode); /画方块函数void RandCake (void); /随机产生食物函数/* Global vars */WorldNode WorldArrayW_YSizeW_XSize; / 定义节点类型的数组大小为游戏界面的长和款WorldNode *HeadNode,*TailNode,*CakeNode; / 定义节点类型的蛇头指针,蛇尾指针,食物指针INT8U LenToAdd = 0; /需要增加的蛇长计数器const INT8U ReverseDir4 = 1,0,3,2; / 第一反方向的常量INT8U ERRNO; / 定义时间常量PDC pdc; / 定义绘图上下文设备INT32S score = 0; / 得分U16 gamelevel = 1;/game为关数,目前为三关,每关只改变速度U16 timeuse; / 游戏用时BOOLEAN isRunning=1; / 定义游戏运行标志U8 flag1=0; /定义 第二关游戏标志U8 flag2=0; / 定义 第三关游戏标志/*AD 定义和初始化*/#define ADCCON_FLAG(0x115) /AD 控制标志#define ADCCON_ENABLE_START_BYREAD(0x11) /AD使能读信号#define rADCCON(*(volatile unsigned *)0x58000000)#define rADCDAT0(*(volatile unsigned *)0x5800000C)#define PRSCVL (496)#define ADCCON_ENABLE_START (0x1)#define STDBM (0x02)#define PRSCEN (0x114)void init_ADdevice()/初始化rADCCON=(PRSCVL|ADCCON_ENABLE_START|STDBM|PRSCEN);int GetADresult(int channel) rADCCON=ADCCON_ENABLE_START_BYREAD|(channel3)|PRSCEN|PRSCVL; / 驱动转换hudelay(10); /延迟10秒钟,转换时间while ( ! ( rADCCON & ADCCON_FLAG ) );/判断是否转换结束return ( 0x3ff & rADCDAT0 );/返回采样值/*蛇的步进速度控制函数*/INT32S GetSpeed(U8 level) / 关口作为传递参数 int ADData; / 定义AD转换数据变量 U16 lastData; /定义换算结果变量 ADData=GetADresult(0); /调用转换函数,获得转换数据 lastData=ADData*3.3*50/1023; /换算成实际电压值if (level=1) return 300+lastData;/根据关口返回对应的速度参数else if (level=2) return 200+lastData; else return 100+lastData; /*根据关数初始化游戏*/void WorldInit(void) INT8U x,y; U16 text1100; WorldNode *xNode; OSSemPend(WorldSem,0,&ERRNO); /等待全局信号量 MoveTo(pdc,20,440); /绘制边框,移动到该点LineTo(pdc,620,440); / 画线 MoveTo(pdc,20,480);LineTo(pdc,620,480); MoveTo(pdc,220,440);LineTo(pdc,220,480);MoveTo(pdc,420,440);LineTo(pdc,420,480);strChar2Unicode(text1,NO.:1000201036 Name:Chen ZhePing);/转换成UNICODETextOut(pdc,20,420,text1,TRUE,FONTSIZE_MIDDLE);/ 显示,学号 文本 For(y=0;yW_YSize;y+) / 定义各个点的属性 for(x=0;xpos.x=x; xNode-pos.y=y; if (gamelevel=1) /根据不同的关口初始化界面 If(x=0|y=0|x=W_XSize-1|y=W_YSize-1) /如果是第一关,则没有障碍物 xNode-Type=TP_Block; xNode-isBlock=1; else xNode-Type=TP_Space; xNode-isBlock=0; else if (gamelevel=2) If(x=W_XSize/2 & (y=W_YSize/3 | y=W_YSize*2/3)|(x=0|y=0|x=W_XSize-1|y=W_YSize-1) /如果是第二关则有两个障碍物 xNode-Type=TP_Block; xNode-isBlock=1; else xNode-Type=TP_Space; xNode-isBlock=0; else If(x=W_XSize/3|x=W_XSize*2/3)&(y=W_YSize/3 | y=W_YSize*2/3)|(x=0|y=0|x=W_XSize-1|y=W_YSize-1) /如果是第三关则有四个障碍物 xNode-Type=TP_Block; xNode-isBlock=1; else xNode-Type=TP_Space; xNode-isBlock=0; /Snake Head xNode=&WorldArrayW_YSize/2W_XSize/2-1; xNode-Type=TP_SkHead; xNode-isBlock=1; HeadNode=xNode; UpdateNextNode(xNode,Left); xNode -PreDir=Left;/Snake Body xNode=&WorldArrayW_YSize/2W_XSize/2; xNode-Type=TP_SkBody; xNode-isBlock=1; UpdateNextNode(xNode,Left); xNode-PreDir=Left; /Snake Tail xNode=&WorldArrayW_YSize/2W_XSize
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 办公文档 > 模板表格


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!