计算机毕业设计84JAVA打飞机游戏毕业设计(4)

2020-02-21 17:28

毕业论文(设计)用纸

位的方法消除)。方法newposition()实现的功能为更新玩家的子弹位置,并且检测玩家子弹与普通敌人的碰撞及记录玩家战果(更新子弹位置的功能可以由使用move()加设置标志位的方法取代;由于设计这个类的时候并没有考虑到添加BOSS等,所以在此检测碰撞,但添加BOOS等功能后,此处的检测完全可以和飞机对飞机等的碰撞检测封装在同一个方法中)。

mybullets类在gameScreen中建立了对象数组huokebullet[9],代表玩家所能发射的9发子弹。

4.3 游戏逻辑及gameScreen类

gameScreen类是游戏的主类,决定着敌人何时出现,控制着敌人出现的方法,判断敌人及玩家是否被击中等。它运行在独立的线程中,以恒定的频率刷新画面。本程序设置为1/20秒。其主逻辑如图4-4所示。

4.3.1 gameScreen类所实现的功能

gameScreen类要实现地图的滚动、敌人飞机的相关属性、玩家的相关属性等功能。 gameScreen类包括了LayerManager,这样所有静态和动态的图象都不需要手动刷新,只需要在LayerManager中加入所有的需要控制的精灵,在统一由LayerManager刷新即可, 因此,在gameScreen中创建LayerManager的对象lm,并在构造函数中实例子化。

其他精灵类的对象如敌人飞机、玩家飞机、玩家飞机的子弹、敌人的子弹、BOSS及BOSS所属的子弹都需在gameScreen()类中建立相应的对象,并在构造喊数中实例化,且由lm.appned()方法添加到LayerManager类对象lm中。

4.3.2 地图的创建

由于手机存储空间的限制,不可能将整张地图完整地存储在手机中,为了节约空间,

往往提出地图中相同的图片组成一张PNG格式的图片,然后象拼图一样拼出地图来,专业的游戏设计者往往自己写一个地图编辑器,以使拼图过程不是那么痛苦。

创建地图就需要使用TiledLayer。TiledLayer指的是由一块一块类似用瓷砖拼凑起来的画面。地图实际即为TiledLayer的一个对象。先利用TiledLayer的构造函数建立TiledLayer,根据构造函数的参数可以给定Cell数组 的大小,并且地图图片切割成等尺寸的画面,并调用setCell()设置具体的图象格内容。地图 图片如图4-5所示。

图4-5 地图 佳木斯大学教务处 第 16 页

毕业论文(设计)用纸

因此,创建一个返回TtiledLayer的方法createBackGround(),以便在gameScreen()的构造函数中调用。在方法中,定义整型数组map1[]以存储Cell的索引值。并使用tiledLayer.setCell(column,row,map1[i])设定TtiledLayer的内容,以形成地图。其中i的值由循环for(int i=0;i

画出地图后,由lm.append()将地图添加到LayerManager类对象lm中。由于地图位于Layer的最低层,即离用户视线最远的层,所以Tiledlayer最后一个被添加到lm中。

4.3.3地图的移动

根据游戏的设定,游戏中地图是向下移动的,实现此功能的方法如下:

首先,在使用createBackGround()函数创建地图数组时,用(row+1)*16-getHeight() 语句对整型变量row2赋值,其中row+1代表地图有多少列,16为地图片的高度,而减去getHeight()是因为要留出一个屏幕的可视区域,由于J2ME规定坐标系中下方向为正,所以使用语句y1=-row2将row2的数值变为负数。

其次,render()函数中,使用lm.setViewWindow(0,0,getWidth(),getHeight()+10000)设定可视区域的范围,(0,0)表示(getWidth() ,getHeight()+10000) 使用lm.paint(g,0,y1)决定 View Window从屏幕的哪里画起。 在run()函数中的while(conti)中, 使用语句y1=y1+1使得每次绘图都使 地图下移1个象素。(参考图4-6)

View Window的起始坐标, (0,y1) y1=y1+1; View Window 向下移动 (0,0) 屏幕 4.3.4 gameScreen类的构造函数

图4-6 gameScreen类的构造函数要将游戏中出现的所有精灵都实例化,实际上,这种方法 严重的占用了内存,但在当时,我并没有意识到这一点。

由于敌人要求不停的出现,但是不可能设置过多的精灵,解决的办法是设定6个Sprite类对象j0、j1、j2及jbullet1、jbullet1、jbullet2,分别代表三架敌机及其配属的子弹。所以在gameScreen类的构造函数分配这6个Sprite类的存储空间,并且使用new Sprite(Image img, int width,int height)实例化这6个类变量。同关尾cboss与游戏

佳木斯大学教务处 第 17 页

毕业论文(设计)用纸

进行中的大飞机其他的Sprite类对象都需要使用相同的方法实例化。同样处于节约内存的考虑,sboss与cboss同用3个Sprite类对象bossbullet0,1,2。

在构造函数中,定义boolean型变量conti=true。conti的作用在于控制是否进行游戏画面的重绘及其他需要在画面重绘前进行的运算。

在构造函数中,将mybullets类里的no和score初始化,现在看来no的初始化没有必要,但是score的初始化是必须的,因为这个变量存储着玩家每次游戏的成绩,如果不在此进行初始化,则玩家重新开始游戏后score并不归0。

4.3.5 关于commandAction()方法

每个创建Command实例的J2ME的应用程序也必须创建实现CommandListener接口的实例。每当用户通过commandAction()方法的方式与命令进行交互的时候,就会通过CommandLIstener.所以实现CommandListener的类必须实现commandAction()方法。

在commandAction()方法中,使用getabel()方法获取命令的标签。如果getLabel()=“暂停”时,表示玩家点击了暂停键,此时,conti赋值为false,游戏画面的绘制及游戏相关的运算暂停,并且,使用removeCommand(c)语句将“暂停”移除,使用addCommand(new Command(\继续\将”继续“按纽”添加进来。当玩家点击“继续“时,conti赋值为true,并且,一定要调用start()方法,否则继续功能不可用。必须调用start()方法的原因是:J2ME的线程已stop()方法拿掉,如果想停止线程的运做,就必须依靠一个旗标(flag),在本程序中,flag就是boolean型变量conti。所以一旦此标识变量被设为false,那么while(conti)循环就会结束,线程也会跟着结束。当用户按下“继续”的时候,start()将重新产生一个线程继续执行相关的运算和画面绘制。

当玩家通关时或者任务失败时,将显示相应信息,并使用上面的方法将“暂停”键变为“返回”键盘,当点击“返回”键时,将返回主菜单选项,调用类lzhhdm里的方法menuscreensecond(),在此方法中,实例化一个MenuScreen类对象,并且使选项“新游戏”改变为”重新开始“(图4-7)。完成此项功能的语句子为MenuScreen.mainmenu[0] =”重新开始”。当选择”重新开始“时,使用gamescreen=new gameScreen(this)将使所有变量重新被初始化,如地图的绘制、敌人出现位置的重置、敌人的数量、玩家飞机的当前位置等。使用gamescreen.start()重新开始程序的循环。

4.3.6 Sprite类对象的碰撞检测及相关属性

佳木斯大学教务处 第 18 页

毕业论文(设计)用纸

游戏进行中,即在while(conti){ }中,需要进行玩家飞 机、子弹与敌机及敌机子弹与玩家飞机的碰撞检测,即使用函 数collidesWith(Sprite,boolean)。由于设计的问题,玩家发 射的子弹与普通敌机的碰撞检测被写在了mybullets类中,并 且只检测第一发子弹是否与敌人相碰撞,如果碰撞为真时,则 使用setVisible(false)函数将敌机隐藏,使用setImage()函 数将子弹精灵的三张图片置换为爆炸图片( 图4-8 )。当敌人剩 余飞机消失后,即所有的敌人都飞出了屏幕后,使用函数

setVisible(true)将敌机重新设置为可见。在按“开火”键时,使用图4-7 setImage()函数将huokebullets重新设定为子弹图片(每次击落敌机后屏幕上的爆炸效果有3团,并且按“开火”后爆炸图片就消失了,实际上setVisavle(false)的应该是子弹数组,而对敌人精灵使用setImage(),这样效果会好一些)。

敌机与玩家的碰撞检测原理同上,都是使用的collidesWith()函数,遗憾的是,我在写这段代码的时候,并没有考虑设置玩家有4次机会,所以对敌人飞机setVisable(fasle)了,而将玩家的飞机换成了爆炸图片,之后,添加了玩家4次机会这个功能,由于玩家被击落后会重新从屏幕下方进入屏幕,所以爆炸的图片一闪而过,效果不是很好。

4.3.7 玩家4次游戏机会的实现方法

根据游戏设置,玩家在每关中有共四次机会,当玩家飞机被击中或撞击爆炸后,程序首先检测整型变量playerno的值,并根据playerno的值决定屏幕右上角所画玩家飞机标志的数量(参考图4-8),playerno的初始值设为3,因为碰撞后才减1,所以玩家共有4次机会,当playerno<0时,游戏结束,同时将变量pver赋值为1,render()或renderboss()函数中,over=1代表在屏幕上GAMEOVER等相关信息,同时,将整型变量inputno赋植为1,以使手机的方向键失效,以消除玩家可以控制爆炸图像移动这个BUG。同时整型变量pzbz赋植为1,以消除玩家爆炸图像继续与敌人进行碰撞检测这个BUG。

当playerno>0时,碰撞后,将变量planert赋值为1,在之后的if(planert==1)判断语句中,重新设定玩家飞机的图片和可视状态,同时使用setPosition()函数设定玩家非的位置在屏幕下方。设定pzbz=1,即不检测碰撞,玩家有短暂时间无敌,无敌时间由屏幕右上角进度条表示。设定inputno=1,即飞入屏幕的过程中手机键盘是不可以用的。设置planert=2,即以上这些设置只执行一便。

佳木斯大学教务处 第 19 页

毕业论文(设计)用纸

在if(planert==2)判断语句中,使用语句move( 0,-2)使飞机自己向上运动,使用if(c1.getY()<( planepo-24))判断飞机是否到达屏幕最下方(planepo 是屏幕下边缘的坐标),如条件为真,则将inputno 设置为1,表示键盘可用,将planert赋值为3,使 其不再执行以上各步。

4.3.8 input()

input()函数的作用是检测用户的输入。 首先使用if(inputno==0)判断用户的输入是否 被禁止,如为真,则用户输入不被禁止。 其次,调用getKeyStates()查询按键的状态。

图4-8 游戏界面 当玩家按方向键时,玩家飞机就向不同的方向运行,这需要使用c1.move(int x,int y)函数,当玩家控制飞机向左或右飞时,需要使c1.setFrame()函数改变飞机的图形(参见图4-7,此时飞机右飞)。同时,还需要判断飞机是否飞出屏幕,如,当飞机右飞时,用if(c1.getX()>(getWidth()-c1.getWidth()))

语句判断(getWith()为屏幕的宽度,c1.getWidth()为玩家飞机c1的宽度),如果条件为真,则使用c1.setPosition((getWidth()-c1.getWidth()),c1.getY())语句将飞机设置在紧靠屏幕右边的位置。上、下、左的设置原理同上。

语句if((keystate&LEFT_PRESSED)==0)的作用是消除左、右飞后在上、下飞时飞机的形态不变的BUG。如果为真,则执行语句c1.setFrame(0),表示只要左键松开飞机的形态都是平飞。

根据游戏设定,玩家一次最多只能发三组子弹,并且子弹有射程限制(在类mybullets中使用整型变量no表示),而当玩家按下“开火“键时,即if((keystate&FIRE_PRESSED)!=0)中判断条件为真时,首先执行循环语句for(int i=0;i<=6;i=i+3),即检测3组子弹中每组的第一发,即0,3,6。其次,检测huokebullet[i].no是否等于1,当等于1时使用语句for( int z=i;z

huokebullet[z].no=huokebullet[z].bulletheight赋予子弹射程。当程序循环运行

佳木斯大学教务处 第 20 页


计算机毕业设计84JAVA打飞机游戏毕业设计(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:HR招聘面试全套面试题库-HR猫猫

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: