brew贪吃蛇游戏

 
功能设计:
控制蛇运动方向:
        用键盘上的↑、↓、←、→控制蛇的运动方向。
        当蛇向一个方向运动时,它的反向键被锁定。
        不能通过连续按住某个方向键而加快蛇的运动。
        若在游戏中,蛇头碰了自己的身体,则游戏结束。
蛇吃食物:
    蛇每吃一个食物增长一节,并且得分加10分。
游戏进行中:
按ok键挂起和恢复(即暂停和继续)
玩家选关:
设置初级,中级和高级三个游戏级别供玩家选择
帮助文档:
帮助玩家进行游戏时的按键操作
游戏结束:
如果在游戏过程中,蛇头碰到了自己的身体,则游戏结束。游戏结束时候,提示player本局得分状况。
   
   
 
数据结构设计:
Snake body由若干像素区域(可以是10*10,5*5,由手机屏幕大小决定,而手机屏幕也将会被分成以snakebody的节点为单位的若干区域,每个节点以该小区域的左上角点坐标为标识)组成,body的每个组成单位是一个node,snake 整个身体是由若干node组成的队列,队头head和队尾rear分别要由两个node*标记( 蛇尾两个 node 是为了方便出列,蛇头两个node是为了判断当前蛇头方向用以决定不按任意键的时候保持snake沿蛇头方向自由前行);另外为snake设置当前行进方向Direction(由snakehead的两个node决定,转弯时要更新Direction,不按任意键时候,沿Direction自由前行,snake不能反向前进)
说明:假如队头和队尾不设双节点,那么可以用双向指针连接队列,但是这样假如蛇身比较长的时候,其实身体中部的操作很少近乎没有,这样耗费了大量的指针空间,以这种代价得不偿失。
事实证明:蛇尾搞两个node,没用!去掉一个!(因为要蛇每前行一步,都要更新头节点和尾节点,此时次尾节点的要更新为倒数第三尾节点,而倒数第三要更新为倒数第四…如此下去,发现次尾节点就是没用的,更新尾节点时,遍历一边蛇身是必须的,因此完全没有必要设置次尾节点了就)
 
Snake 成员变量设计:
(1) 二维标志数组 Boolean isPartOfSnake[scrWidth/n][scrHeight/n],其中n是snake node小矩形的边长,这个二维数组用于标记screen上每个node是否属于snakebody,目的是方便检查body是否产生回路,一旦产生了回路,则game over(即蛇头碰到自己的身体)。
(2) 是否需要产生食物标志 Boolean NeedFood,该位为false,说明有食物,player可以按up,down,left和right进行猎食,不按任意键,snake沿direction方向自由前进;一旦食物被吃掉,该位置true,并且马上产生随机坐标(x,y),在该坐标处出现食物,随即该位置false。
(3)本局游戏得分 int pScore,记录当前游戏的得分情况,每吃到一个食物加10分,每当game over时候,显示当局得分情况。
(4)当前行进方向runDir,用来锁定按下↑、↓、←、→时候与当前行进方向反向的那个。
(5) 当前食物所在位置坐标foodPos,该坐标由随机函数产生,产生之后需要进行处理,这些坐标必须是node节点的左上角点,并且在屏幕的有效范围内。
(6)snake行进速度Intervals,以此作为snake前进一个节点的时间间隔,游戏等级的划分是通过设置此间隔的大小来实现的,等级越高间隔越小,反之间隔越大。但是也不能无限制的小下去,因此设定全局常量MIN_INTERVALS,每当游戏速度将要超过最大值,就要将此间隔置为MIN_INTERVALS。
 
菜单设计:
开始:开局一场新游戏
选关:设置子菜单,游戏分三个等级:初级,中级和高级,每个级别的snake有不同的行进速度
记录:记录该游戏的最高分
帮助:给出一些游戏按键的使用帮助和提示
退出:退出该游戏
 
Snake 中遇到的问题以及解决:
(1)主菜单可以显示,但是start不起作用
   原因在于菜单控件是在mainmenu中定义并创建实例的,不作为pMe的成员,所以在函数结束时销毁了就,设菜单控件为pMe的成员,也就相当于全局变量就ok了。
总结:学习阶段很多代码都是拼凑而来,不反对“拿来主义”,但一定要注意变量的作用范围和生存周期,不要仅仅停留在能看懂code的低要求,要仔细寻味每个变量和没行代码的意义。
 
(2)在initSnakeBody中用malloc开辟的Node在SnakeRunFreely中free出错(也就是snake每前行一步,要生成一个新的头节点并且删除当前尾节点),一运行到此就死,如果到了程序结束时候再free显然也只是free了最后snakebody上的节点,过程中那些delete的尾节点并没有free,显然已经违反了c语言的内存管理思想,更别说brew平台内存相当小的实际情况。
原因在于brew有自己的内存管理函数MALLOC,MALLOCREC,FREE,FREEIF等等,虽然MALLOC和FREE跟c的malloc,free很相像,但是用c的free就死,用FREE就可以。
       总结:凡事不要想当然,在编译能够通过,运行出错的情况,如果逻辑和思想是完全毋庸置疑的(譬如动态开辟的节点用完要释放),就要考虑特定环境的语法了,可以编译通过并不代表用的正确!
 
(3)用ISHELL_LoadBitmap加载Bitmap时,路径总弄不好,相对的弄不好,绝对路径仍然不行!很诧异!
       解决:放弃了直接load,改用了资源加载,用ISHELL_LoadResBitmap解决了问题,但是前者需要进一步研究下。
 
(4)食物的位置跟蛇头node区域不能完全对准,也就是蛇只能吃到一半食物,这显然太假了,还有就是因为判断食物是否被吃掉的flag设在了食物node区域的左上角,所以吃掉半个的情况很难将游戏继续下去,很多情况这个flag没有重置,所以不会产生新的食物。
解决:只有对屏幕进行适当裁剪,所谓的裁剪就是使得screenHeight和screenWidth正好是body节点的整数倍,这样也对食物产生的随机坐标做节点的整数倍处理,才能对齐蛇头和食物,使得它能够完全吃掉food。
 
(5)食物的产生是通过在产生的随机坐标处加载food图片来实现的,但是运行多次发现有时候食物就不见了,通过单步调试发现随机坐标已经产生了,并且在合法的屏幕坐标内
       原因:没有判断食物坐标是否产生在了snakeBody之上,因此即使产生了坐标在body之上,被body覆盖了
       解决:产生随机坐标时,加个while语句,while随机坐标是snakeBody的节点坐标,再重新产生,直到此坐标不在body上。
 
(6)选关Select Stage菜单中,按ok不能返回正确值,多次运行,当前菜单项得到focus并不发送触发菜单项命令,而是按下ok键才代表着当前菜单项被选中,触发对应命令事件。
       结论:不能受某些已有观念左右,某种意义上单步是解决问题的好途径。
 
(7)关于文件读写操作的问题:以_OFM_READ打开文件无异常,以_OFM_READWRITE就会出错,编译可以正常通过,模拟器上运行就会出错。百思不得其解,单步多次,现象相同,原因未果。上网搜索这方面资料,发现建工程project和mif文件都要勾选“File”复选框,勾选保存之后还是不可以,再找资料才发现这不是程序的问题,而是模拟器的问题,有前人说过在模拟器上运行程序以READ方式操作文件可以,以READWRITE方式就不可以,也就是模拟器只支持读file,不支持写入file。
总结:单步到一个语句,如果还是出错,而很多书上例子都这样写的话(也就是语句绝对没有问题的话),先要检查工程类型和mif权限,再不行要相信自己没错,是IDE或者模拟器的问题,自信点儿,不然太浪费时间。
 
(8)主菜单quit菜单项加入dialog,询问玩家是否真的要退出。由dialog返回主菜单,主菜单不能响应事件,原因clr事件写在了evt_key_press里面了,而evt_key_press是没有clr键的,只能写在evt_key事件里面!
总结:单步了多次,虽然花费了较多时间,但是对于dialog的消息处理机制有了比较深的认识。
 
(9)位图的设计,一些菜单项的图标和食物的bitmap,为了能和snakebody的一个节点比例相当,还有就是跟屏幕节点区域大小相当,就要自己画了,网上下载的图片总是不太合适,用im自由截图又很难精确到像素级。
       解决:只有用ms word画图工具画了,再在pbrush里面拉动大小了,很笨的办法,但是做出来的图自己感觉还比较符合要求!
 
Snake 游戏进一步完善的方向:
(1)最高分记录可以记录最高成绩的前三名,保存在record.txt中,同时pMe增加成员变量:int数组型。每当applet start,就要初始化这个record数组,从record.txt中读取这三个最高分,到本局游戏结束,把本局得分和record记录的前三名成绩做比较,能进入前三名,则更新record.txt中的记录,并加载显示一个“奖杯”之类的图片提示并祝贺玩家进入前三甚至打破最高分记录。鉴于模拟器对file不支持写入操作,该功能有待在真机上运行时实现。
 
(2)提高界面的友好性,增加跟玩家的交互性,譬如玩家在进行某些操作时候可以弹出一个小对话框进行提示,询问等。在选关以后可以进行以下提示“Senior已选定”,在游戏进行时玩家选择退出也可以进行提示“确实要退出吗?”等等!因为brew API中的对话框并不像MFC中的afxmessagebox那样简便易用,再者考虑到snake游戏本身的简单通俗性,忽略了这个改进。
 
BrewSdk 使用过程遇到的问题总结:
(1)先装VC,再装BrewSdk,VC还是不能找到Brew App Wizard,安装BrewSdkTools即可;
(2)安装了BrewSdkTools,向导中MIF Editor打不开,要换装更低版本的BrewSdkTools;
(3)找不到AEEModGen.h,提示缺少了BREWDIR环境变量,添加环境变量,值为BrewSdk路径,重启机器;
(4)运行helloworld,找不到mif文件,原因是创建mif时默认为mfx,选择另外两项扩展名为mif v1或者mif v2 ;
(5)两个应用程序运行结果一样,其实就是创建bid文件是填入的class id一样了;
(6)动态applet是不允许使用静态或者全局变量的,尽管在SDK中可能没有问题,但在device中就会出现问题,设备将因为不能定位到全局变量而失败;
(7)setTimer()只起一次作用,要想连续动作就要连续触发;
(8)资源文件名不能用大写;
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值