现有应用程序的分析.docx
- 文档编号:24258813
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:27
- 大小:99.96KB
现有应用程序的分析.docx
《现有应用程序的分析.docx》由会员分享,可在线阅读,更多相关《现有应用程序的分析.docx(27页珍藏版)》请在冰豆网上搜索。
现有应用程序的分析
对已有程序——手机游戏潜艇大战的实现分析
一、游戏介绍
(1)利用方向键来改变军舰的运行方向;
(2)确定键发射导弹,击中敌人得分,击中自己人扣分;
(3)选项键可以更换背景和背景音乐。
二、游戏的流程和类结构
(1)游戏流程
本游戏的基本运行流程是在MIDlet启动后把整个画布作为一个线程,随时准备响应用户按键操作的KeyPressed()方法,100ms扫描一次潜艇和水雷等物体的运行状态。
在扫描潜艇和水雷运动时,执行各个物体画面的移动方法。
程序并不为每隔新增潜艇和水雷开启一个新线程,太多线程会造成程序的性能直线下降;而是将每一个物体类型直接加入到画布中,每当一个新物体产生,将直接在画布上画出;当物体消除时,将直接在画布上被消除。
这样就形成一种注册机制,所有游戏物体的产生和消除都需要画布注册,画布拥有不同类型物体的所有“名单”,所以,当执行移动命令是只需要遍历画布中所有游戏物体,依次执行每隔游戏物体中定义的移动方法即可。
(2)游戏的类结构
在本游戏的设计过程中,严格按照面向对象的程序设计思想对程序进行设计,主要显示类包括主界面类、游戏画布类、菜单类、选项类、音乐类、说明类和分别代表军舰、水雷和潜艇的各种实体类。
●FIRMIDlet:
是游戏的主类,控制着游戏的生命周期,在FIRMIDlet类中的startapp()方法中先载入游戏画面:
在FIRMIDlet类中定义了一个static型的quitapp()方法,以方便在游戏过程中随时点击“退出”键来结束改游戏,和一个static型的setcurrent方法方便在其他类中调用不同的显示对象。
startapp()方法当中,加载本游戏的选择菜单;quitapp()方法以结束midlet应用程序并释放内存;采用setcurrent()方法来设置display对象中要显示的屏幕画面。
●FIRCanvas:
画布类,负责绘制游戏中的各种游戏物体,并响应用户的按键操作。
●Boat:
军舰类,定义游戏中军舰的外观、移动和绘制方法。
●Submariner:
潜艇类,定义游戏中潜艇的外观、移动和绘制方法。
●Bomb:
水雷类。
定义游戏中水雷的外观,移动,控制以及碰撞检测的方法。
三、具体设计
(1)游戏画布类FIRCanvas的实现
FIRCanvas继承Canvas类,用来实现整个游戏的主界面。
代码具体如下:
publicFIRCanvas(){
CMD_BG=newCommand("更改背景",8,2);
CMD_SOUND=newCommand("切换声音",8,2);
CMD_BACK=newCommand("退出",8,2);
addCommand(CMD_BG);
屏幕坐标示意图
addCommand(CMD_SOUND);
addCommand(CMD_BACK);
setCommandListener(this);
try{
imgBack=Image.createImage(getWidth(),getHeight());
gBack=imgBack.getGraphics();
sound=SoundEffects.getInstance();
boatImage[0]=Image.createImage("/res/ship0.png");
boatImage[1]=Image.createImage("/res/ship1.png");
bombImage=Image.createImage("/res/boom.png");
sImage1[0]=Image.createImage("/res/q1.png");
sImage1[1]=Image.createImage("/res/h2.png");
sImage2[0]=Image.createImage("/res/r1.png");
sImage2[1]=Image.createImage("/res/q2.png");
boomImage[0]=Image.createImage("/res/b.png");
boomImage[1]=Image.createImage("/res/f1.png");
boomImage[2]=Image.createImage("/res/b2.png");
}catch(Exceptione){
e.printStackTrace();}
width=this.getWidth();//获得屏幕宽度
height=this.getHeight();//获得屏幕高度
imgBack=Image.createImage(getWidth(),getHeight());
gBack=imgBack.getGraphics();
//创建次画面和次画笔
offScreen=Image.createImage(width,height);
offG=offScreen.getGraphics();
boat=newBoat(boatImage,width);
init(0);
init
(1);
bomb=newBomb(bombImage,0,0,height);
Threadt=newThread(this);
t.start();
playMusic();}
privatevoidinit(intnum){
if(num==0){
submarine[0]=newSubmarine(sImage1,width,height,0,boomImage);}
if(num==1){
submarine[1]=newSubmarine(sImage2,width,height,1,boomImage);}}
●类中声明了游戏中需要的各种对象,并载入游戏中的图片
●在类中启动新线程,调用线程类得run()方法来运行程序
protectedvoidpaint(Graphicsg){
//清屏
offG.setColor(0xffffff);
offG.fillRect(0,0,width,height);
offG.setColor(0);
//绘制
if(imgBack!
=null){
offG.drawImage(imgBack,0,0,Graphics.TOP|Graphics.LEFT);}
boat.paint(offG);
submarine[0].paint(offG);
submarine[1].paint(offG);
if(bomb.isDisplay){
bomb.paint(offG);}
//绘制得分
offG.drawString("得分:
"+score,4,4,Graphics.TOP|Graphics.LEFT);
//将次画面贴到主画面
g.drawImage(offScreen,0,0,Graphics.TOP|Graphics.LEFT);}
●Paint()方法用来游戏中的各种物体图片绘制到屏幕上
publicvoidkeyPressed(intkeyCode){//转换为游戏动作
intaction=this.getGameAction(keyCode);
switch(action){
caseCanvas.LEFT:
//向左
isRepeated=true;
boatDirection=Boat.BOAT_MOVE_LEFT;
break;
caseCanvas.RIGHT:
isRepeated=true;
boatDirection=Boat.BOAT_MOVE_RIGHT;
break;
caseCanvas.FIRE:
if(!
bomb.isDisplay){
bomb.isDisplay=true;
bomb.setX(boat.x+boat.getBoatImageWidth()/2-bomb.getImageWidth()/2);
bomb.setY(boat.Y+boat.getBoatImageHeight()-
bomb.getImageHeight());
}//设置坐标
break;
}
//重新绘制
repaint();
}
●keyPressed()方法用来判断用户的按键,从而控制军舰的移动
protectedvoiddrawBackground(Graphicsg)
{bytebX=0,bY=0;
intimgWidth,imgHeight;
Imageimage;
if(back<0)
{g.setColor(0x00AAAAFF);
g.fillRect(0,0,CanvasWidth,CanvasHeight);
}else
{try
{image=Image.createImage(BackArray[back]);
imgWidth=image.getWidth();
imgHeight=image.getHeight();
while(bY*imgHeight<=CanvasHeight)
{bX=0;
while(bX*imgWidth<=CanvasWidth)
{g.drawImage(image,bX*imgWidth,bY*imgHeight,Graphics.TOP|Graphics.LEFT);
bX++;}
bY++;}
}catch(IOExceptionioe)
{
System.out.println("Imgnotfound:
"+BackArray[back]);
g.setColor(0x00AAAAFF);
g.fillRect(0,0,CanvasWidth,CanvasHeight);
}
}
}
●drawBackground()方法用来绘制背景图片
publicvoidrun(){
while(isRunning){
try{
Thread.sleep(100);
}catch(Exceptione){}
if(isRepeated){
boat.move(boatDirection);}
if(!
submarine[0].isIsBoom()){
submarine[0].move();
}else{//播放爆炸效果
submarine[0].boom();}
if(!
submarine[1].isIsBoom()){
submarine[1].move();
}else{//播放爆炸效果
submarine[1].boom();}
if(bomb.isDisplay){
bomb.move();
if(bomb.collidesWith(submarine[0])){
bomb.handlecollidesWith(submarine[0]);
score-=10;
}
if(bomb.collidesWith(submarine[1])){
bomb.handlecollidesWith(submarine[1]);
score+=10;
}}
System.gc();
repaint();}}
●run()方法用来运行程序
privatevoidplayMusic(){
sound.stopMusic();
switch(music){
case0:
break;
case1:
sound.playSpringMusic();
break;
case2:
sound.playCityMusic();
break;
case3:
sound.playFlowerMusic();
break;
default:
break;}}
●playMusic()方法用来执行音乐的选择和播放
publicvoidcommandAction(Commandc,Displayabled)
{if(c==CMD_BACK)
{midlet.instructionsBack();
}elseif(c==CMD_SOUND)
{music++;
if(music==5)music=0;
playMusic();}
elseif(c==CMD_BG)
{back++;
if(back==BackArray.length)back=0;
drawBackground(gBack);
repaint();}}}
●按钮的事件处理方法:
更换背景,更换背景音乐,退出游戏
(2)军舰类的实现
游戏中有用户控制的军舰类Boat主要用来在屏幕中绘制出军舰的外观,并定义其移动的方法。
具体代码如下:
publicBoat(Image[]boatImage,intwidth){
this.boatImage=boatImage;
this.width=width;
this.boatImageWidth=boatImage[0].getWidth();
this.boatImageHeight=boatImage[0].getHeight();}
●类的构造器Boat()中声明要显示的图片
publicvoidpaint(Graphicsg){
g.drawImage(boatImage[direction],x,Y,Graphics.TOP|Graphics.LEFT);}
●paint()方法用来绘制军舰的外观
publicvoidmove(intdirection){
this.direction=direction;
if(this.direction==BOAT_MOVE_LEFT){
if(x>dx){x-=dx;
}else{x=0;
}
}
if(this.direction==BOAT_MOVE_RIGHT){
if(x+boatImageWidth x+=dx; }else{x=width-boatImageWidth;}} } ●move()方法用来定义军舰的移动方法 军舰是向左或向右移动,要进行边界检测如果到边后就不能再移动。 (3)潜艇类的实现 游戏中的潜艇类submarine主要用来在屏幕中绘制出潜艇的外观,并定义生成潜艇、移动潜艇以及潜艇爆炸方法,具体代码定义如下: publicSubmarine(Image[]submarineImage,intwidth,intheight,intnum,Image[]boom){ this.submarineImage=submarineImage; this.width=width; this.height=height; this.num=num; this.boom=boom; this.imageWidth=submarineImage[0].getWidth(); this.imageHeight=submarineImage[0].getHeight(); generate();} ●类的构造器submarine()中声明要显示的图像,并产生一个潜艇对象 publicvoidpaint(Graphicsg){ if(! isBoom){ g.drawImage(submarineImage[direction],x,y, Graphics.TOP|Graphics.LEFT); }else{//爆炸效果 if(boomIndex==-1){ Return;} g.drawImage(boom[boomIndex],x,y, Graphics.TOP|Graphics.LEFT);}} ●Paint()方法用来绘制潜艇的外观 publicvoidboom(){//如果爆炸完毕 if(boomIndex==2){ isBoom=false;//修改标志 boomIndex=-1; generate();}//重新生成潜艇 if(boomIndex<2){ boomIndex++;}} ●Boom()方法用来定义爆炸效果 publicvoidmove(){ if(! isBoom){//没有爆炸 if(direction==0){//向右移动 if(x x+=dx; }else{ x=width+dx; direction=1;}}//改变方向 if(direction==1){//向右移动 if(x+imageWidth>dx){//边界检测 x-=dx; }else{ x=dx-imageWidth; direction=0;}}}//改变方向 ●Move()方法用来定义潜艇的移动方法 privatevoidgenerate(){ if(num==0){ x=-imageWidth; y=height-30; direction=0;} if(num==1){ x=width; y=height-60; direction=1;}} ●generate()方法用来生成潜艇对象,生成潜艇坐标 点A的坐标是潜艇0的坐标,A位于X轴的负方向所以横坐标等于潜艇图片宽度的相反数,纵坐标设定一个固定值。 点B的坐标是潜艇1的坐标,横坐标等于屏幕宽度,纵坐标等于一个固定值。 如下图: 潜艇生成坐标 publicbooleanisIsBoom(){ returnisBoom; } ●isIsBoom()方法用来判断潜艇是否爆炸 (4)水雷类的实现 游戏中水雷类bomb主要用来在屏幕中绘制出水雷的外观,并定义移动的方法,最重要的是在该类中定义了水雷和潜艇的碰撞检测方法,具体代码定义如下: publicBomb(ImagebombImage,intx,inty,intheight){ this.bombImage=bombImage; this.x=x; this.y=y; this.height=height; //初始化图片高度和宽度 this.imageHeight=bombImage.getHeight(); this.imageWidth=bombImage.getWidth();} ●类的构造器bomb()中声明要显示的图像 publicvoidpaint(Graphicsg){ g.drawImage(bombImage,x,y,Graphics.TOP|Graphics.LEFT);} ●Paint()方法用来绘制潜艇外观 publicvoidmove(){ if(y y+=dy; }else{ //使炸弹不可见 水雷移动示意图 isDisplay=false;}} ●Move()方法定义水雷的移动 判断水雷的纵坐标是否等于屏幕的高度,如果小于继续向下单位移动,否则水雷消失。 publicbooleancollidesWith(Submarinesubmarine){ //炸弹中心点的坐标 intbx=x+imageWidth/2; intby=y+imageHeight/2; //潜艇中心点的坐标 intsx=submarine.getX()+submarine.getImageWidth()/2; intsy=submarine.getY()+submarine.getImageHeight()/2; //判断中心点之间的距离 if((Math.abs(bx-sx)<(imageWidth+submarine.getImageWidth())/2)&& (Math.abs(by-sy)<(imageHeight+submarine.getImageHeight())/2)){ returntrue; }else{returnfalse;}} ●collidesWith()方法用来碰撞检测 判断两个对象中心点之间的距离,水雷中心点A(x1,y1)的坐标是(水雷的横坐标+图片宽度的一半,水雷的纵坐标+图片高度的一半),潜艇中心点B(x2,y2)的坐标是(潜艇的横坐标+图片宽度的一半,潜艇的纵坐标+图片高度的一半)。 如果|x1-x2|<水雷图片宽度+潜艇图片宽度的一半,则水雷图片在如图A标明的区域移动。 如果|y1-y2|<水雷图片高度+潜艇图片高度的一半,则水雷图片在如图B标明的区域移动。 两个条件同时成立,在这个区域内水雷与潜艇就是相互碰撞的,图C所示: publicvoidhandlecollidesWith(Submarinesubmarine){ isDisplay=false;//设置炸弹不可见 submarine.setIsBoom(true);}//潜艇爆炸 ●handlecollidesWith()方法用来进行碰撞处理 移动区域A 图5-5中心点坐标位置 移动区域B 移动区域C (5)音乐类的实现 该类的主要功能是使用MIDP1.0MediaAPI播放背景音乐,具体代码如下: publicvoidplayCityMusic() {springPlayer=null; flowerPlayer=null; cityPlayer=createPlayer("/city.mid","audio/midi"); startPlayer(cityPlayer);} ●playCityMusic()方法用来播
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 现有 应用程序 分析
![提示](https://static.bdocx.com/images/bang_tan.gif)