⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lw.txt

📁 关于java之坦克游戏开发中的论文设计
💻 TXT
📖 第 1 页 / 共 5 页
字号:

和CommandListener。在类menuscreen中定义了lowColor和

highColor、highBGColor三个整型变量及布尔型变量co。其

中lowColor赋值为0x000000FF,代表兰色,higColor赋值为

0x00FF0000,代表红色,highBGColor赋值为0x00CCCCCC,代表

图4-2 游戏的菜单 
 
兰灰色,即背景条。当玩家按住上或下键时,在函数keyPressed

(int code)中的整型变量menuIndex相应的减1或加1,相应的,在paint()函数中会根据menuIndex绘制选项是否被选中。在函数run()中,如果co为真,则不停的repaint(),设置co的意义在于,当进入游戏主画面后,co赋值为false,以终止绘制选项的repaint(),提高游戏速度。                                          

    当移动选项条到某项,并点击ok时,在commandAction()方法中根据 menuIndex                                                           

的值判断选择了哪个选项,列如当选择“关于”时,将调用lzhhdm类中的renwuShow()方法以显示”关于”界面(图4-3),在renwuShow()方法中,Form类对象a=null,表示清空Form,并重新调用用append()方法在表单上放置StringItem类的实例以显示游戏关于信息,“帮助“界面的显示与”关于“界面相同,只不过调用的是helpShow()方法。






而Java技术在无线应用方面的优势非常明显:

1.  应用程序可按需下载,而不是购买由硬件商提供的套件,可升级空间大。4.2 mybullets类   

在介绍游戏主类gameScreen类之前,应该先简要说明一下玩家子弹类mybullets类,实际上,mybullets类是应该删除的,其要实现的功能应该放在gameScreen类中,但是由于设计游戏的过程也是一个学习的过程,而在当时,我并没有意识到这一点。                                            

     Mybullets类继承自Sprite类,以实现玩家子弹的相关功能。首先,创建子弹状态数组private int[][] bullets,其中,[i][0]代表子弹的X坐标,[i][1]代表子弹的Y坐标,[i][2]代表子弹Y方向速度,[i][3]代表子弹存活状态(由于此类是在早期设计的,而之后子弹存活状态使用了子弹射程作为标志位,所以其并没有起到作用)。类中定义的方法setfirstposition()起到定义玩家子弹发射坐标的作用(此方法在设计时起到的作用是消除每按一次开火玩家子弹位置就重新定位这个BUG,但是,这个BUG完全可以用设置标志位的方法消除)。方法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所示。

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

    画出地图后,由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)表示View Window的起始坐标,(getWidth() ,getHeight()+10000)  

使用lm.paint(g,0,y1)决定

View  Window从屏幕的哪里画起。

在run()函数中的while(conti)中,

使用语句y1=y1+1使得每次绘图都使

地图下移1个象素。(参考图4-6)

4.3.4 gameScreen类的构造函数

gameScreen类的构造函数要将游戏中出现的所有精灵都实例化,实际上,这种方法

严重的占用了内存,但在当时,我并没有意识到这一点。

由于敌人要求不停的出现,但是不可能设置过多的精灵,解决的办法是设定6个Sprite类对象j0、j1、j2及jbullet1、jbullet1、jbullet2,分别代表三架敌机及其配属的子弹。所以在gameScreen类的构造函数分配这6个Sprite类的存储空间,并且使用new Sprite(Image img, int width,int height)实例化这6个类变量。同关尾cboss与游戏进行中的大飞机其他的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("继续",Command.OK,2));将”继续“按纽”添加进来。当玩家点击“继续“时,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类对象的碰撞检测及相关属性

    游戏进行中,即在while(conti){ }中,需要进行玩家飞

机、子弹与敌机及敌机子弹与玩家飞机的碰撞检测,即使用函

数collidesWith(Sprite,boolean)。由于设计的问题,玩家发

射的子弹与普通敌机的碰撞检测被写在了mybullets类中,并

且只检测第一发子弹是否与敌人相碰撞,如果碰撞为真时,则

使用setVisible(false)函数将敌机隐藏,使用setImage()函

数将子弹精灵的三张图片置换为爆炸图片( 图4-8 )。当敌人剩

图4-7
 
余飞机消失后,即所有的敌人都飞出了屏幕后,使用函数

setVisible(true)将敌机重新设置为可见。在按“开火”键时,使用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,即以上这些设置只执行一便。

     在if(planert==2)判断语句中,使用语句move(

0,-2)使飞机自己向上运动,使用if(c1.getY()<(

planepo-24))判断飞机是否到达屏幕最下方(planepo

是屏幕下边缘的坐标),如条件为真,则将inputno

设置为1,表示键盘可用,将planert赋值为3,使

其不再执行以上各步。

4.3.8 input() 

 input()函数的作用是检测用户的输入。

首先使用if(inputno==0)判断用户的输入是否

被禁止,如为真,则用户输入不被禁止。

图4-8 游戏界面
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -