基于J2ME的小球快跑游戏毕业论文_第1页
基于J2ME的小球快跑游戏毕业论文_第2页
基于J2ME的小球快跑游戏毕业论文_第3页
基于J2ME的小球快跑游戏毕业论文_第4页
基于J2ME的小球快跑游戏毕业论文_第5页
已阅读5页,还剩28页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

PAGEPAGE32石家庄科技信息职业学院毕业论文题目:基于J2ME的小球快跑游戏专业班级:软件技术(游戏方向)09-24班

基于J2ME的小球快跑游戏摘要:手机是人们日常生活中所用的非常频繁的通信工具。随着JAVA技术的不断更新提高,J2ME技术的出现,使得手机游戏越来越成为我们关注的焦点。J2ME技术目前最流行的就是在制作手机游戏方面,JAVA手机的出现使得这一技术更有它的用武之地,发挥着他灵活、轻便、快捷的作用。J2ME平台被是最杰出的手机游戏手机游戏平台,它一些非常重要的特征对开发者都有很大益处。因为J2ME应用在不同设备上都是便携式的,他们常常可以在网络上下载和执行。本设计通过DriftBall和GameView等类进行小球快跑游戏设计,最后编程实现了全过程。关键词:J2MEDriftBallGameView目录设计内容及过程……………4(1)游戏策划………………… 4(2)设计背景………………..4(3)游戏框架设计…………… 5游戏主菜单的开发…………5(1)WelcomeView类的代码框架………… 5(2)WelcomeView类的主要成员方法.………6(3)WelcomeThread类的开发…………8(4)菜单界面的用户交互事件处理……….……9游戏界面模块的开发…………………… 11(1)GameView的成员变量11(2)GameThread类的代码框架13(3)GameMenuThread类的开发13游戏中各个图层的开发……………………..15(1)地图图层的开发…………………. 15(2)其他图层的开发与实现………………… 18游戏后台逻辑的开发…………………....21(1)小球的运动控制21(2)小球的碰撞检测25传感器计算模块的开发27(1)BallListener类的开发27(2)RotateUtil类的开发28设计总结参考文献…………31设计内容及过程本设计针对小球快跑实现了新游戏、选关、恭喜过关,继续或冲完等过程。可以清楚的演示各个画面的切换和一些游戏开发的类库。游戏策划本游戏从类型上看属于动作类通关游戏,因此在游戏开发前进行的策划中需要考虑到诸如剧情规划、关卡设计等内容剧情规划:由于本游戏主要是以玩法取胜,而不是靠游戏情节来吸引玩家,所以游戏的剧情的规划可以尽量简单或者干脆没有关卡设计:关卡设计是本游戏的一个重点,在关卡设计的时候,如何保证难易程度的循环渐进和关卡之间的互异性以及关卡的可玩性是需要重视的问题。目标受众:本游戏的操作方式十分简单,各个年龄阶段的玩家都可以快速掌握。目标平台:本游戏的目标平台为MTK。呈现技术:本游戏的游戏画面采用了图元技术,所以地图的设计也是一个重点,同时增强了游戏的空间感。(2)设计背景游戏中,首先必须要有个主应用程序类,其次,为了把程序的画面呈现出来,就是要有画布;为了比较容易管理地图、增加或修改地图比较方便,应该把地图和画布分开。这其中需要先了解游戏中应用到的类。WelcomeView类继承自SurfaceView类,其主要负责播放欢迎动画和显示游戏主菜单。GameView类继承自SurfaceView,其主要负责游戏主画面的渲染。GameMenuThread负责实现游戏中菜单的逐行的效果。GameMap类负责负责提供游戏中的地图信息,GameMap中存储了所有关卡的信息,并对外提供了方法用于获得指定关卡的地图信息。DriftBall类继承自Activity,其主要负责在不同的View之间进行切换,同时也负责处理用户单击屏幕事件。BaiiListener类继承自SensorListener类,气质要负责监听手机姿态的变化并将捕获到的数据传递给RotateUtil进行分析计算。RotateUtil类主要负责接收手机姿态的变化数据,并根据一系列算法计算出在这种姿态下的小球的运动方向。(3)游戏框架设计游戏基本框架图:图1小球快跑游戏基本框架游戏主菜单的开发WelcomeView类的代码框架代码如下:packagewyf.wpf; //声明包语句importandroid.content.Context; //引入相关类importandroid.content.res.Resources; //引入相关类importandroid.graphics.Bitmap; //引入相关类importandroid.graphics.BitmapFactory; //引入相关类importandroid.graphics.Canvas; //引入相关类importandroid.graphics.Color; //引入相关类importandroid.graphics.Matrix; //引入相关类importandroid.graphics.Paint; //引入相关类importandroid.view.SurfaceHolder; //引入相关类importandroid.view.SurfaceView; //引入相关类/**该类继承自View,负责欢迎界面的绘制*/publicclassWelcomeViewextendsSurfaceViewimplementsSurfaceHolder.Callback{ DriftBallfather; WelcomeThreadwt; WelcomeDrawThreadwdt; Bitmap[]bmpBackScreen; //后台背景的动画帧 Bitmap[]bmpStartOrQuit; //开始和退出的两个大球图片 Bitmap[]bmpSoundOption; //声音选项的两个大球图片 intstatus=-1; //状态值,为0表示待命,1表示开始或退出按钮按下,2为显示加载中 intselectedIndex=-1; //被选中的命令,只能是开始或退出 intbackIndex; //后台帧动画的索引 Matrixm; //Matrix对象,负责 int[][]planetCoordinate={ //三个球的位置数组 {60,120}, {120,300}, {180,220} }; //构造器,初始化成员变量 publicWelcomeView(DriftBallfather){ super(father); wt=newWelcomeThread(this); getHolder().addCallback(this); wdt=newWelcomeDrawThread(this,getHolder()); initBitmap(father); //初始化图片 this.father=father; status=0; m=newMatrix(); }WelcomeView类主要成员方法代码如下:packagewyf.wpf; //声明包语句importorg.openintents.sensorsimulator.hardware.SensorManagerSimulator;//引入相关类importandroid.app.Activity; //引入相关类importandroid.graphics.Rect; //引入相关类importandroid.hardware.SensorManager; //引入相关类importandroid.media.MediaPlayer; //引入相关类importandroid.os.Bundle; //引入相关类importandroid.os.Handler; //引入相关类importandroid.os.Message; //引入相关类importandroid.view.KeyEvent; //引入相关类importandroid.view.MotionEvent; //引入相关类importandroid.view.View; //引入相关类importandroid.view.Window; //引入相关类importandroid.view.WindowManager; //引入相关类/**该类为游戏的主类,所有的View对象在这里有所引用,主要的功能是实现游戏*的流程控制,提供游戏需要的常量,在视图之间进行切换。*/publicclassDriftBallextendsActivity{ publicstaticfinalintSTATUS_PLAY=0; //游戏进行中 publicstaticfinalintSTATUS_PAUSE=1; //游戏暂停 publicstaticfinalintSTATUS_WIN=2; //通过一关 publicstaticfinalintSTATUS_LOSE=3; //丢掉一条命 publicstaticfinalintSTATUS_OVER=4; //送完命了,游戏结束 publicstaticfinalintSTATUS_PASS=5; //通全关 publicstaticfinalintMAX_LIFE=5; //最大生命数 publicstaticfinalintMAX_LEVEL=5; //最大关卡数 intlevel=1; //初始状态等级为1 intlife=MAX_LIFE; //初始状态生命数最大 RectrectStart; //开始圆球按钮的矩形框 RectrectSoundOption; //声音选项圆球按钮的矩形框 RectrectQuit; //推出圆形按钮的矩形框 RectrectContinue; //继续游戏菜单项的矩形框 RectrectSoundAlter; //声音选项菜单项的矩形框 RectrectHelp; //帮助菜单项的矩形框 RectrectBackToMain; //回到主菜单菜单项的矩形框 RectrectGameMsgBox; //屏幕中间提示消息的矩形框 MediaPlayermpGameMusic; //游戏背景音乐 MediaPlayermpPlusLife; //加命的音乐 MediaPlayermpMissileHit; //导弹打中的音乐 MediaPlayermpGameWin; //通过了一关的音乐 MediaPlayermpGameLose; //损失一条命的音乐 MediaPlayermpBreakOut; //显示菜单和掉入陷阱以及被吃掉的音乐 booleanwantSound=true; //标志位,记录是否播放音乐 ViewcurrView; //记录当前显示的View GameViewgv; //游戏视图的引用 WelcomeViewwv; //欢迎视图的引用 BallListenerbl; //继承自SensorListener的监听器 HelpViewhv; //帮助视图 //@1======对源代码进行如下修改以连接SensorSimulator// SensorManagermySensorManager; SensorManagerSimulatormySensorManager; HandlermyHandler=newHandler(){ publicvoidhandleMessage(Messagemsg){ //重写handleMessage方法 switch(msg.what){ case0: //0为收到来自WelcomeView的开始游戏命令 gv=newGameView(DriftBall.this); setContentView(gv); //设置当前View currView=gv; //记录当前View startSensor(); //开启传感器 图2游戏开始界面WelcomeThread的开发代码如下:packagewyf.wpf; //声明包语句/**该类继承自Thread,为欢迎界面的后台线程,*负责修改相关数据,达到动画效果*/publicclassWelcomeThreadextendsThread{ WelcomeViewfather; //WelcomeView引用 intsleepSpan=100; //休眠时间 booleanflag=false; //构造器,接收WelcomeView对象引用 publicWelcomeThread(WelcomeViewfather){ this.father=father; this.flag=true; } }菜单界面的用户交互事件处理代码如下: //重写的方法,用于接收和处理用户点击屏幕事件 @Override publicbooleanonTouchEvent(MotionEventevent){ if(event.getAction()==MotionEvent.ACTION_UP){ intx=(int)event.getX(); inty=(int)event.getY();if(currView==wv){ //当前为欢迎界面 if(rectStart.contains(x,y)){ //点下开始的圆球 wv.status=1; //设置状态为1,有按钮按下 wv.selectedIndex=0; //设置被选中的按钮为开始按钮 } elseif(rectSoundOption.contains(x,y)){ //点下切换声音的圆球 wantSound=!wantSound; //切换标志位 if(!wantSound){ //如果当前在播放声音,停 if(mpGameMusic.isPlaying()){ try{ mpGameMusic.pause(); //暂停游戏背景音乐 }catch(Exceptione){} } } elseif(wantSound){ //如果当前没有播放声音,播放 if(!mpGameMusic.isPlaying()){ try{ mpGameMusic.start(); //播放游戏背景音乐 }catch(Exceptione){} } } } elseif(rectQuit.contains(x,y)){ //点下退出的圆球 wv.status=1; //设置状态为1,有按钮按下 wv.selectedIndex=1; //设置被选中的按钮为退出按钮 } } elseif(currView==gv){ //当前为游戏界面在显示 if(gv.status==STATUS_PAUSE){ if(rectContinue.contains(x,y)){ //点下继续游戏菜单 gv.gmt.isOut=true; //菜单开始退出屏幕 } elseif(rectSoundAlter.contains(x,y)){ //点下切换声音菜单 wantSound=!wantSound; if(!wantSound){ //判断记录值的真假 if(mpGameMusic.isPlaying()){ try{ mpGameMusic.pause(); //暂停声音 }catch(Exceptione){} } } elseif(wantSound){ if(!mpGameMusic.isPlaying()){ try{ mpGameMusic.start(); //播放声音 }catch(Exceptione){} } } gv.gmt.isOut=true; } elseif(rectHelp.contains(x,y)){ //点下帮助菜单 gv.gmt.isOut=true; //淡出菜单 gv.pauseGame(); //暂停游戏 hv=newHelpView(this); //创建HelpView对象 setContentView(hv); //切屏 currView=hv; } elseif(rectBackToMain.contains(x,y)){ //点下回主菜单 gv.gmt.isOut=true; //淡出菜单 wv=newWelcomeView(this); //创建欢迎界面 setContentView(wv); //切屏 currView=wv; //记录当前View pauseSensor(); //暂停Sensor gv.shutAll(); //关闭gv的附属线程 gv=null; } } elseif(gv.status==STATUS_WIN){ //闯过一关 if(rectGameMsgBox.contains(x,y)){ gv.initGame(); gv.resumeGame(); //开始下一关的游戏 } } elseif(gv.status==STATUS_PASS||gv.status==STATUS_OVER){ //当前状态为通全关或死完了 if(rectGameMsgBox.contains(x,y)){ //判断点击的位置 wv=newWelcomeView(this); //创建欢迎界面 setContentView(wv); //切屏 currView=wv; //记录View pauseSensor(); //暂停监听器 gv.shutAll(); //关闭gv附属线程 gv=null; } } } } returntrue; } 游戏界面模块的开发GameView的成员变量代码如下:packagewyf.wpf; //声明包语句importjava.util.ArrayList; //引入相关类importandroid.content.res.Resources; //引入相关类importandroid.graphics.Bitmap; //引入相关类importandroid.graphics.BitmapFactory; //引入相关类importandroid.graphics.Canvas; //引入相关类importandroid.view.SurfaceHolder; //引入相关类importandroid.view.SurfaceView; //引入相关类importandroid.view.SurfaceHolder.Callback; //引入相关类importstaticwyf.wpf.DriftBall.*; //引入相关类/**该类继承自SurfaceView,主要功能是绘制游戏屏幕,对后台的绘制或其他线程*进行控制。*/publicclassGameViewextendsSurfaceViewimplementsCallback{ intscreenWidth=320; //屏幕宽度 intscreenHeight=480; //屏幕高度 intbackY; //x坐标总是为零 intnebulaX; //星云的x坐标 intnebulaY; //星云的y坐标 intballX; //小球的横坐标 intballY; //小球的纵坐标 inttileSize=20; //图元的大小 intdirection=-1; //小球运动方向,上为0,顺时针依次为1~7 intvelocity=4; //小球运动速度 inteatIndex; //吃人动画帧索引 intstatus; //游戏状态 inttrapIndex; //陷阱动画索引 booleanshowMenu; //是否显示菜单 DriftBallfather; //DriftBall引用 DrawThreaddt; //绘制线程 GameThreadgt; //后台数据的修改线程 CannonThreadct; //大炮线程 GameMenuThreadgmt; //游戏菜单线程 Meteorolite[]meteoArray; //陨石数组 ArrayList<Missile>alMissile=newArrayList<Missile>(); //存放导弹集合 ArrayList<Cannon>alCannon=newArrayList<Cannon>(); //存放大炮集合 BitmapbmpStar; //星空图片 BitmapbmpNebula; //星云图片 BitmapbmpBall; //小球图片 BitmapbmpTile; //地图图元,即路的图片 Bitmap[]bmpMeteo; //陨石图片 Bitmap[]bmpEat; //吃人图片 BitmapbmpHome; //家的图片 Bitmap[]bmpTrap; //陷阱图片 BitmapbmpCannon; //大炮图片 BitmapbmpMissile; //导弹图片 BitmapbmpPlusLife; //加命图片 BitmapbmpMultiply; //乘号图片,用以显示命数 Bitmap[]bmpNumber; //数字图片 Bitmap[]bmpMenuItem; //菜单项图片数组 BitmapbmpGameWin; //游戏胜利图片 BitmapbmpGameOver; //游戏结束图片 BitmapbmpGamePass; //游戏通关图片 (2)GameThread类的代码框架代码如下:packagewyf.wpf; //声明包语句/**这个类主要负责绘制元素的数据变化,如控制陨石和星云的帧何时切换*同时还负责,移动小球。不同的元素的不同的换帧间隔是通过帧控制计数器*来实现的。移动小球的同时还会相应地进行碰撞检测*/importstaticwyf.wpf.DriftBall.*; //引入DriftBall类的静态常量publicclassGameThreadextendsThread{ GameViewfather; //GameView对象引用 intsleepSpan=25; //休眠时间 intbackCounter; //背景帧控制计数器 intnebulaCounter; //星云帧控制计数器 inteatCounter; //吃掉小球的帧控制计数器 inttrapCounter; //陷阱帧控制计数器 intmeteoCounter; //陨石帧控制计数器 booleanflag=false; //外层循环 booleanisGameOn=false; //游戏是否在进行 //构造器 publicGameThread(GameViewfather){ this.father=father; this.flag=true; }GameMenuThraed类的开发代码如下:packagewyf.wpf; //声明包语句/**该类继承自Thread类,主要负责将菜单及菜单项在屏幕上的位置*进行改变以达到动画效果*/publicclassGameMenuThreadextendsThread{ DriftBallfather; //主类引用 booleanflag; //循环控制变量 booleanisIn; //是否是淡入菜单 booleanisOut; //是否是淡出菜单 intsleepSpan=20; //睡眠时间 int[][]menuCoordinate={ //菜单在没进来之前的位置,分别是菜单背景和4个菜单项 {350,0}, {400,30}, {450,80}, {500,130}, {550,180} }; //构造器 publicGameMenuThread(DriftBallfather){ this.father=father; father.gv.menuCoordinate=this.menuCoordinate; flag=true; isIn=true; } //线程执行方法 publicvoidrun(){ intinIndex=0; //淡入的索引顺序 intoutIndex=4; //淡出时的索引顺序 while(flag){ if(isIn){ //菜单进屏幕 for(inti=inIndex;i<father.gv.menuCoordinate.length;i++){ father.gv.menuCoordinate[i][0]-=25; //向屏幕内移动菜单项 if(father.gv.menuCoordinate[i][0]==150){ //判断菜单项是否已到位 inIndex=i+1; //将开始索引下移,即不再改变到位的菜单项坐标 } } if(inIndex==5){ //如果所有菜单项都移动到位 isIn=false; //设置isIn标志位为false } } elseif(isOut){ //菜单出屏幕 father.gv.menuCoordinate[outIndex][0]+=10; //向屏幕外移动菜单项 if(father.gv.menuCoordinate[outIndex][0]>=320){ //判断是否将菜单项移出屏幕 outIndex--; //改移动前一个菜单项 if(outIndex<0){ //判断是否所有的菜单项都移出屏幕 if(father.currView==father.gv){ //如果当前View是GameView father.gv.resumeGame(); //调用resumeGame方法恢复游戏 } flag=false; //停止线程的执行 } } } try{ //线程休眠 Thread.sleep(sleepSpan); } catch(Exceptione){ e.printStackTrace(); } } }}五.游戏中各个图层的开发地图图层的开发代码如下:packagewyf.wpf; //声明包语句/**该类主要存储一个静态成员,3为数组,里面存放所有地图,每个地图*都是一个二维数组。同时还提供了一个静态方法,调用之后返回一个*地图的二维数组*/publicclassGameMap{ staticbyte[][][]map={//地图,为0则空,为1则路,2为家,3是加命的,4是吃小球的,5是陷阱,6是大炮 { //第一关 {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,1,1,1,5,1,1,1,1,0,0,0,0,0,0}, {0,0,0,1,0,0,0,0,0,1,1,1,1,0,0,0}, {0,0,0,1,1,1,1,1,1,1,0,0,1,0,0,0}, {0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0}, {0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0}, {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, {0,1,0,0,1,0,0,0,0,0,1,0,0,0,1,0}, {0,1,0,0,1,0,0,0,0,0,1,0,0,0,1,0}, {0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0}, {0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0}, {0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0}, {0,0,1,1,1,1,1,0,1,1,1,1,1,0,0,0}, {0,4,0,1,0,0,0,0,0,0,0,1,0,0,4,0}, {4,3,1,1,1,1,1,0,1,1,1,1,1,1,3,4}, {0,1,0,0,0,0,1,0,1,0,0,0,0,0,1,0}, {0,1,0,0,0,0,1,0,1,0,0,0,0,0,1,0}, {0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0}, {0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, {0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, {0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0}, {0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0} }, { //第二关 {1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,1,0,0,0,0,1,1,1,5,1,1,1,1,0}, {0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0}, {0,1,1,1,5,1,0,1,0,0,1,1,1,1,1,0}, {0,1,0,0,0,1,0,1,0,0,1,0,4,0,4,0}, {0,1,0,4,3,1,0,1,1,1,1,1,1,1,1,0}, {0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0}, {0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0}, {4,1,1,1,1,1,0,1,0,0,0,1,1,1,0,0}, {0,0,1,0,0,0,0,1,0,0,4,1,0,0,0,0}, {0,0,1,1,1,1,1,1,0,0,0,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,1,3,4,0,0}, {0,3,1,5,1,1,1,1,0,0,0,1,0,0,0,0}, {0,1,0,0,0,0,0,1,0,0,4,1,0,0,0,0}, {0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0}, {0,1,1,1,3,5,1,1,1,1,1,1,5,1,1,0}, {0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0}, {0,0,0,1,0,0,0,1,0,1,1,0,0,0,1,0}, {0,1,1,1,1,1,1,1,1,1,0,0,2,0,1,0}, {0,1,0,0,0,0,0,1,0,1,0,0,1,0,1,0}, {0,1,0,0,4,0,0,1,0,1,0,0,1,1,1,0}, {0,1,1,1,1,1,1,1,1,1,5,1,1,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} }, { //第三关 {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,0,0,0,0,0,1,3,1,0,0,0,0,0,0}, {0,1,1,1,5,1,1,1,0,1,0,0,0,0,0,0}, {0,0,0,0,0,0,0,1,0,1,1,1,5,1,1,0}, {0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,0}, {0,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0}, {0,1,0,0,0,3,1,1,0,1,1,1,1,1,3,0}, {0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0}, {0,1,1,1,1,0,1,0,0,1,0,0,0,0,0,6}, {0,3,0,0,1,0,1,1,1,1,0,0,0,0,0,0}, {0,4,1,1,1,0,0,0,0,0,0,0,0,0,0,0}, {0,1,1,0,0,0,0,1,1,1,1,1,1,3,0,0}, {0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0}, {0,1,0,0,0,0,0,1,0,0,1,0,0,1,1,1}, {0,1,1,1,5,1,1,1,0,0,1,0,0,1,0,1}, {0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1}, {0,1,1,1,1,1,1,5,1,1,1,1,1,1,0,1}, {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {0,1,1,1,1,1,1,1,1,1,0,0,0,4,0,1}, {0,0,0,0,3,0,0,0,0,1,0,0,0,3,0,1}, {0,0,0,0,4,0,4,0,0,1,1,1,1,1,1,1}, {0,0,0,0,0,0,3,0,0,1,0,3,0,0,0,0}, {0,1,1,1,5,1,1,1,1,1,0,4,0,0,0,0}, {0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0} }, { //第四关 {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,1,0,4,0,0,0,0,0,0}, {0,0,1,1,1,1,1,1,0,1,1,1,5,1,3,0}, {0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0}, {0,1,1,1,5,1,1,1,1,1,0,0,0,0,1,0}, {0,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0}, {0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0}, {0,1,1,1,1,1,1,1,5,1,0,0,0,0,0,0}, {0,4,0,0,0,0,0,1,0,1,1,1,1,1,1,0}, {0,0,0,1,1,1,1,1,0,0,4,0,0,0,1,0}, {0,0,0,1,0,0,0,1,1,1,1,1,1,1,1,0}, {0,1,1,1,1,1,1,1,0,0,0,0,1,0,1,0}, {0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0}, {0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0}, {0,3,1,1,1,5,1,1,1,1,1,1,1,5,3,0}, {6,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0}, {0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0}, {0,0,0,3,1,1,0,0,4,1,0,0,0,0,0,0}, {0,0,0,1,0,0,0,1,1,1,1,5,1,1,0,0}, {0,3,1,1,0,0,0,1,0,0,0,0,0,1,0,0}, {0,1,0,0,0,4,0,1,0,0,0,0,0,1,0,0}, {0,1,1,1,1,1,1,3,0,0,0,0,0,1,1,0}, {0,0,0,4,0,0,0,0,0,0,0,0,0,0,1,2} }, { //第五关 {1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,1,0,0,0,4,0,0,0,0,0,0,0,0,0}, {0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0}, {0,0,1,0,0,0,0,0,0,1,1,5,1,1,0,0}, {0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0}, {0,4,1,1,1,1,1,5,1,1,1,1,1,1,1,0}, {0,1,1,0,1,0,0,0,0,0,1,0,0,0,1,0}, {0,1,0,0,1,0,0,0,0,1,1,0,0,0,1,0}, {0,1,0,0,1,0,0,0,0,1,0,0,0,0,1,0}, {0,1,0,0,1,0,0,0,0,3,1,1,1,1,1,0}, {0,1,0,0,1,0,0,6,0,0,0,0,0,0,1,0}, {0,1,1,1,1,3,0,0,0,0,0,0,4,3,1,0}, {0,0,0,0,0,1,1,3,0,0,0,0,0,0,1,0}, {0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,4}, {0,1,1,5,1,1,0,1,1,1,1,1,0,0,1,0}, {0,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0}, {0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0}, {0,1,1,1,1,1,1,1,1,1,1,3,1,1,0,0}, {0,0,0,0,0,3,0,0,0,1,0,0,0,1,0,0}, {0,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0}, {0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0}, {0,0,0,0,0,1,1,1,1,1,0,0,0,1,0,0}, {0,1,1,1,1,1,0,0,0,1,1,1,1,3,0,0}, {2,1,0,0,4,0,0,0,0,0,0,0,0,0,0,6} } }; //方法,返回指定关卡的地图数组 publicstaticbyte[][]getMap(intlevel){ returnmap[level-1]; }}(2)其他图层的开发与实现代码如下:packagewyf.wpf; //声明包语句/**该类代表陨石对象,将陨石的坐标,当前帧号封装起来*有一个成员方法负责初始化陨石的信息*/publicclassMeteorolite{ intx; //陨石x坐标 inty; //陨石y坐标 booleanup; //为true则在地图图层上,为false则在地图图层下 intindex; //旋转角度 publicMeteorolite(){ //构造器,调用init方法进行初始化 init(); } publicvoidinit(){//方法:初始化成员变量 x=(int)(Math.random()*290); //随机产生X坐标 y=-(int)(Math.random()*250); //随机产生Y坐标 up=(Math.random()>0.5?true:false); //随机设置是否在上层的标志位 index=(int)(Math.random()*8); //随机产生陨石动画的帧索引 }}packagewyf.wpf; //声明包语句importjava.util.ArrayList; //引入相关类importandroid.content.res.Resources; //引入相关类importandroid.graphics.Bitmap; //引入相关类importandroid.graphics.BitmapFactory; //引入相关类importandroid.graphics.Canvas; //引入相关类importandroid.view.SurfaceHolder; //引入相关类importandroid.view.SurfaceView; //引入相关类importandroid.view.SurfaceHolder.Callback; //引入相关类importstaticwyf.wpf.DriftBall.*; //引入相关类/**该类继承自SurfaceView,主要功能是绘制游戏屏幕,对后台的绘制或其他线程*进行控制。*/publicclassGameViewextendsSurfaceViewimplementsCallback{ intscreenWidth=320; //屏幕宽度 intscreenHeight=480; //屏幕高度 intbackY; //x坐标总是为零 intnebulaX; //星云的x坐标 intnebulaY; //星云的y坐标 intballX; //小球的横坐标 intballY; //小球的纵坐标 inttileSize=20; //图元的大小 intdirection=-1; //小球运动方向,上为0,顺时针依次为1~7 intvelocity=4; //小球运动速度 inteatIndex; //吃人动画帧索引 intstatus; //游戏状态 inttrapIndex; //陷阱动画索引 booleanshowMenu; //是否显示菜单 DriftBallfather; //DriftBall引用 DrawThreaddt; //绘制线程 GameThreadgt; //后台数据的修改线程 CannonThreadct; //大炮线程 GameMenuThreadgmt; //游戏菜单线程 Meteorolite[]meteoArray; //陨石数组 ArrayList<Missile>alMissile=newArrayList<Missile>(); //存放导弹集合 ArrayList<Cannon>alCannon=newArrayList<Cannon>(); //存放大炮集合 BitmapbmpStar; //星空图片 BitmapbmpNebula; //星云图片 BitmapbmpBall; //小球图片 BitmapbmpTile; //地图图元,即路的图片 Bitmap[]bmpMeteo; //陨石图片 Bitmap[]bmpEat; //吃人图片 BitmapbmpHome; //家的图片 Bitmap[]bmpTrap; //陷阱图片 BitmapbmpCannon; //大炮图片 BitmapbmpMissile; //导弹图片 BitmapbmpPlusLife; //加命图片 BitmapbmpMultiply; //乘号图片,用以显示命数 Bitmap[]bmpNumber; //数字图片 Bitmap[]bmpMenuItem; //菜单项图片数组 BitmapbmpGameWin; //游戏胜利图片 BitmapbmpGameOver; //游戏结束图片 BitmapbmpGamePass; //游戏通关图片 图3游戏运行界面五.游戏后台逻辑的开发(1)小球的运动控制代码如下packagewyf.wpf; //声明包语句/**这个类主要负责绘制元素的数据变化,如控制陨石和星云的帧何时切换*同时还负责,移动小球。不同的元素的不同的换帧间隔是通过帧控制计数器*来实现的。移动小球的同时还会相应地进行碰撞检测*/importstaticwyf.wpf.DriftBall.*; //引入DriftBall类的静态常量publicclassGameThreadextendsThread{ GameViewfather; //GameView对象引用 intsleepSpan=25; //休眠时间 intbackCounter; //背景帧控制计数器 intnebulaCounter; //星云帧控制计数器 inteatCounter; //吃掉小球的帧控制计数器 inttrapCounter; //陷阱帧控制计数器 intmeteoCounter; //陨石帧控制计数器 booleanflag=false; //外层循环 booleanisGameOn=false; //游戏是否在进行 //构造器 publicGameThread(GameViewfather){ this.father=father; this.flag=true; } //线程执行方法 publicvoidrun(){ while(flag){ while(isGameOn){ //星空的运动 backCounter++; if(backCounter==50/sleepSpan){ //星空是500ms移动一下 father.backY-=1; backCounter=0; if(father.backY==-600){ father.backY=0; } } //星云的运动 nebulaCounter++; if(nebulaCounter==40/sleepSpan){ father.nebulaY+=1; nebulaCounter=0; if(father.nebulaY>=480){ father.nebulaY=-150; father.nebulaX=(int)(Math.random()*250); } } //陨石的运动 meteoCounter++; for(Meteorolitem:father.meteoArray){ m.y+=2; if(m.y>=father.screenHeight){ //超出屏幕边界则重新初始化 m.init(); } } if(meteoCounter==150/sleepSpan){ for(Meteorolitem:father.meteoArray){ m.index=(m.index+1)%8; } meteoCounter=0; } //吃人动画 eatCounter++; if(eatCounter==200/sleepSpan){ father.eatIndex=(father.eatIndex+1)%father.bmpEat.length; eatCounter=0; } //陷阱动画 trapCounter++; if(trapCounter==300/sleepSpan){ father.trapIndex=(father.trapIndex+1)%father.bmpTrap.length; trapCounter=0; } //移动炮弹 try{ if(father.alMissile.size()!=0){ for(Missilem:father.alMissile){ m.moveAndCheck(); } } } catch(Exceptione){ } //移动小球 checkAndMoveBall(); try{ Thread.sleep(sleepSpan); } catch(Exceptione){ e.printStackTrace(); } } try{ Thread.sleep(800); } catch(Exceptione){ e.printStackTrace(); } } } //检查移动小球 publicvoidcheckAndMoveBall(){ switch(father.direction){ case0: //方向向上 father.ballY-=father.velocity; //Y方向上的移动 if(checkCollision()){ //检测是否发生碰撞 father.ballY+=father.velocity; //若发生碰撞就撤销移动 } break; case1: //方向右上 father.ballY-=father.velocity; //Y方向上的移动 if(checkCollision()){ //检测是否发生碰撞 father.ballY+=father.velocity; //若发生碰撞就撤销移动 } father.ballX+=father.velocity; //X方向上的移动 if(checkCollision()){ //检测是否发生碰撞 father.ballX-=father.velocity; //若发生碰撞就撤销移动 } break; case2: //方向向右 father.ballX+=father.velocity; //X方向上的移动 if(checkCollision()){ //检测是否发生碰撞 father.ballX-=father.velocity; //若发生碰撞就撤销移动 } break; case3: //方向右下 father.ballX+=father.velocity; //X方向上的移动 if(checkCollision()){ //检测是否发生碰撞 father.ballX-=father.velocity; //若发生碰撞就撤销移动 } father.ballY+=father.velocity; //Y方向上的移动 if(checkCollision()){ //检测是否发生碰撞 father.ballY-=father.velocity; //若发生碰撞就撤销移动 } break; case4: //方向向下 father.ballY+=father.velocity; //Y方向上的移动 if(checkCollision()){ //检测是否发生碰撞 father.ballY-=father.velocity; //若发生碰撞就撤销移动 } break; case5: //方向左下 father.ballX-=father.velocity; //X方向上的移动 if(checkCollision()){ //检测是否发生碰撞 father.ballX+=father.velocity; //若发生碰撞就撤销移动 } father.ballY+=father.velocity; //Y方向上的移动 if(checkCollision()){ //若发生碰撞就撤销移动 father.ballY-=father.velocity; //若发生碰撞就撤销移动 } break; case6: //方向向左 father.ballX-=father.velocity; //X方向上的移动 if(checkCollision()){ //若发生碰撞就撤销移动 father.ballX+=father.velocity; //若发生碰撞就撤销移动 } break; case7: //方向左上 father.ballX-=father.velocity; //X方向上的移动 if(checkCollision()){ //若发生碰撞就撤销移动 father.ballX+=father.velocity; //若发生碰撞就撤销移动 } father.ballY-=father.velocity; //Y方向上的移动 if(checkCollision()){ //若发生碰撞就撤销移动 father.ballY+=father.velocity; //若发生碰撞就撤销移动 } break; } } 小球的碰撞检测代码如下: publicbooleancheckCollision(){ intsize=father.tileSize; //获取地图图元大小 byte[][]map=father.currMap; //获取地图矩阵 introw=0; intcol=0; //检查左上角 col=father.ballX/size; //求出左上角在地图中所占的列数 row=father.ballY/size; //求出左上角在地图中所占的行数 if(col>=0&&col<map[0].length&&row>=0&&row<map.length&&map[row][col]==0){ returntrue; } //检查右上角 col=(father.ballX+size-1)/size;//求出右上角在地图中所占的列数 row=father.ballY/size; //求出右上角在地图中所占的行数 if(col>=0&&col<map[0].length&&row>=0&&row<map.length&&map[row][col]==0){ returntrue; } //检查右下角 col=(father.ballX+size-1)/size;//求出右下角在地图中所占的列数 row=(father.ballY+size-1)/size;//求出右下角在地图中所占的行数 if(col>=0&&col<map[0].length&&row>=0&&row<map.length&&map[row][col]==0){ returntrue; } //检查左下角 col=father.ballX/size; //求出左下角在地图中所占的列数 row=(father.ballY+size-1)/size; //求出左下角在地图中所占的行数 if(col>=0&&col<map[0].length&&row>=0&&row<map.length&&map[row][col]==0){ returntrue; } //检查左边界 if(father.ballX<0){ returntrue; } //检查上边界 if(father.ballY<0){ returntrue; } //检查右边界 if(father.ballX+size>father.currMap[0].length*size){ //前面的size指的是小球的尺寸,后面的是指图元尺寸 returntrue; } //检查下边界 if(father.ballY+size>father.currMap.length*size){ returntrue; } //检查是否遇到其他情况 col=father.ballX/size; row=father.ballY/size; if(col==(father.ballX+size-1)/size&&row==(father.ballY+size-1)/size){ //判断小球是否正好在某个格子里 switch(father.currMap[row][col]){ case2: //到家了 father.status=STATUS_WIN; //设置游戏状态为STATUS_WIN if(father.father.wantSound){ //如有需要播放声音 try{ father.father.mpGameWin.start(); }catch(Exceptione){} } isGameOn=false; //暂停GameThread的执行 if(father.father.level==MAX_LEVEL){ //检查是否是最后一关 father.status=STATUS_PASS; //设置游戏状态为STATUS_PASS } else{ father.father.level+=1; //如果不是最后一关,就将关卡加1 } break; case3: //吃到加命的 if(father.father.wantSound){ //如有需要播放声音 try{ father.father.mpPlusLife.start(); } catch(Exceptione){} } father.ballX=col*size; //修正小球的X坐标 father.ballY=row*size; //修正小球的Y坐标 father.currMap[row][col]=1; //将地图矩阵中该位置改为道路 father.father.life+=1; //小球的生命数加1 break; case4: //被吃了 father.status=STATUS_LOSE; //设置游戏状态为STATUS_LOSE if(father.father.wantSound){ //如有需要播放声音 try{ father.father.mpBreakOut.start(); }catch(Exceptione){} } father.father.life-=1; //小球的生命数减1 if(father.father.life<=0){ father.status=STATUS_OVER; //如果小球生命耗尽,设置状态位为STATUS_OVER } else{ father.ballX=0; //复位小球坐标 father.ballY=0; } break; }传感器计算模块的开发BallListener类的开发代码如下:packagewyf.wpf; //声明包语句importandroid.hardware.SensorListener;//引入相关类importandroid.hardware.SensorManager;//引入相关类/**该类继承自SensorListener,主要功能是感应传感器的姿态数据*通过onSensorChanged方法读取数据,并调用RoatatUtil中的静态*方法来确定小球应该移动的方向。*/publicclassBallListenerimplementsSensorListener{ DriftBallfather; //DriftBall引用 inttimeSpan=500; //500MS检查一次 longstartTime; //记录开始的时间 publicBallListener(DriftBallfather){ //构造器,初始化成员变量 this.father=father; startTime=System.currentTimeMillis(); //记录系统时间作为当前时间 } @Override publicvoidonAccur

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论