1、现有应用程序的分析 对已有程序手机游戏潜艇大战的实现分析一、游戏介绍(1) 利用方向键来改变军舰的运行方向; (2) 确定键发射导弹,击中敌人得分,击中自己人扣分; (3) 选项键可以更换背景和背景音乐。二、游戏的流程和类结构(1)游戏流程本游戏的基本运行流程是在MIDlet启动后把整个画布作为一个线程,随时准备响应用户按键操作的KeyPressed()方法,100ms扫描一次潜艇和水雷等物体的运行状态。在扫描潜艇和水雷运动时,执行各个物体画面的移动方法。程序并不为每隔新增潜艇和水雷开启一个新线程,太多线程会造成程序的性能直线下降;而是将每一个物体类型直接加入到画布中,每当一个新物体产生,将直
2、接在画布上画出;当物体消除时,将直接在画布上被消除。这样就形成一种注册机制,所有游戏物体的产生和消除都需要画布注册,画布拥有不同类型物体的所有“名单”,所以,当执行移动命令是只需要遍历画布中所有游戏物体,依次执行每隔游戏物体中定义的移动方法即可。(2)游戏的类结构在本游戏的设计过程中,严格按照面向对象的程序设计思想对程序进行设计,主要显示类包括主界面类、游戏画布类、菜单类、选项类、音乐类、说明类和分别代表军舰、水雷和潜艇的各种实体类。FIRMIDlet:是游戏的主类,控制着游戏的生命周期,在FIRMIDlet类中的startapp()方法中先载入游戏画面:在FIRMIDlet类中定义了一个st
3、atic型的quitapp()方法,以方便在游戏过程中随时点击“退出”键来结束改游戏,和一个static型的setcurrent方法方便在其他类中调用不同的显示对象。startapp()方法当中,加载本游戏的选择菜单;quitapp()方法以结束midlet应用程序并释放内存;采用setcurrent()方法来设置display对象中要显示的屏幕画面。FIRCanvas:画布类,负责绘制游戏中的各种游戏物体,并响应用户的按键操作。Boat:军舰类,定义游戏中军舰的外观、移动和绘制方法。Submariner:潜艇类,定义游戏中潜艇的外观、移动和绘制方法。Bomb:水雷类。定义游戏中水雷的外观,移
4、动,控制以及碰撞检测的方法。三、具体设计(1)游戏画布类FIRCanvas的实现FIRCanvas继承Canvas类,用来实现整个游戏的主界面。代码具体如下: public FIRCanvas() CMD_BG = new Command(更改背景,8, 2); CMD_SOUND = new Command(切换声音, 8, 2); CMD_BACK = new Command(退出, 8, 2); addCommand(CMD_BG); 屏幕坐标示意图 addCommand(CMD_SOUND); addCommand( CMD_BACK); setCommandListener(this
5、); try imgBack = Image.createImage (getWidth(), getHeight(); gBack = imgBack.getGraphics(); sound = SoundEffects.getInstance(); boatImage0 = Image.createImage(/res/ship0.png); boatImage1 = Image.createImage(/res/ship1.png); bombImage = Image.createImage(/res/boom.png); sImage10 = Image.createImage(/
6、res/q1.png); sImage11 = Image.createImage(/res/h2.png); sImage20 = Image.createImage(/res/r1.png); sImage21 = Image.createImage(/res/q2.png); boomImage0 = Image.createImage(/res/b.png); boomImage1 = Image.createImage(/res/f1.png); boomImage2 = Image.createImage(/res/b2.png); catch (Exception e) e.pr
7、intStackTrace( ); width = this.getWidth(); /获得屏幕宽度 height = this.getHeight();/获得屏幕高度 imgBack = Image.createImage (getWidth(),getHeight(); gBack = imgBack.getGraphics(); /创建次画面和次画笔 offScreen = Image.createImage(width, height); offG = offScreen.getGraphics(); boat = new Boat(boatImage, width); init(0)
8、; init(1); bomb = new Bomb(bombImage, 0, 0, height); Thread t = new Thread(this); t.start( ); playMusic(); private void init(int num) if (num = 0) submarine0 = new Submarine(sImage1, width, height, 0, boomImage); if (num = 1) submarine1 = new Submarine(sImage2, width, height, 1, boomImage);类中声明了游戏中需
9、要的各种对象,并载入游戏中的图片在类中启动新线程,调用线程类得run()方法来运行程序protected void paint(Graphics g) /清屏 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); submarine0.paint(offG); submarine1.pai
10、nt(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()方法用来游戏中的各种物体图片绘制到屏幕上 public void keyPressed(int keyCode) /转换为游戏动作 int action = this.getGameAction(keyCode);
11、 switch (action) case Canvas.LEFT: /向左 isRepeated = true; boatDirection = Boat.BOAT_MOVE_LEFT; break; case Canvas.RIGHT: isRepeated = true; boatDirection = Boat.BOAT_MOVE_RIGHT; break; case Canvas.FIRE: if (!bomb.isDisplay) bomb.isDisplay = true; bomb.setX(boat.x+boat.getBoatImageWidth()/2-bomb.getI
12、mageWidth() / 2); bomb.setY(boat.Y + boat.getBoatImageHeight() - bomb.getImageHeight(); /设置坐标 break; /重新绘制 repaint(); keyPressed()方法用来判断用户的按键,从而控制军舰的移动 protected void drawBackground (Graphics g) byte bX = 0, bY = 0; int imgWidth, imgHeight; Image image; if (back 0) g.setColor (0x00AAAAFF); g.fillRec
13、t (0, 0, CanvasWidth, CanvasHeight); else try image = Image.createImage (BackArrayback ); imgWidth = image.getWidth(); imgHeight = image.getHeight(); while (bY * imgHeight = CanvasHeight) bX = 0; while (bX * imgWidth dx) x -= dx; else x = 0; if (this.direction = BOAT_MOVE_RIGHT) if (x + boatImageWid
14、th width - dx) x += dx; else x = width - boatImageWidth;move()方法用来定义军舰的移动方法军舰是向左或向右移动,要进行边界检测如果到边后就不能再移动。(3)潜艇类的实现游戏中的潜艇类submarine主要用来在屏幕中绘制出潜艇的外观,并定义生成潜艇、移动潜艇以及潜艇爆炸方法,具体代码定义如下: public Submarine(Image submarineImage, int width, int height, int num,Image boom) this.submarineImage = submarineImage; th
15、is.width = width; this.height = height; this.num = num; this.boom = boom; this.imageWidth = submarineImage0.getWidth(); this.imageHeight = submarineImage0.getHeight(); generate(); 类的构造器submarine()中声明要显示的图像,并产生一个潜艇对象 public void paint(Graphics g) if (!isBoom) g.drawImage(submarineImagedirection, x, y
16、, Graphics.TOP | Graphics.LEFT); else /爆炸效果 if (boomIndex = -1) Return; g.drawImage(boomboomIndex, x, y, Graphics.TOP | Graphics.LEFT);Paint()方法用来绘制潜艇的外观public void boom() /如果爆炸完毕 if (boomIndex = 2) isBoom = false;/修改标志 boomIndex = -1; generate();/重新生成潜艇 if (boomIndex 2) boomIndex+;Boom()方法用来定义爆炸效果
17、public void move() if (!isBoom) /没有爆炸 if (direction = 0) /向右移动 if (x dx) /边界检测 x -= dx; else x = dx - imageWidth; direction = 0; /改变方向Move()方法用来定义潜艇的移动方法 private void generate() if (num = 0) x = -imageWidth; y = height - 30; direction = 0; if (num = 1) x = width; y = height - 60; direction = 1; gene
18、rate()方法用来生成潜艇对象,生成潜艇坐标点A的坐标是潜艇0的坐标,A位于X轴的负方向所以横坐标等于潜艇图片宽度的相反数,纵坐标设定一个固定值。点B的坐标是潜艇1的坐标,横坐标等于屏幕宽度,纵坐标等于一个固定值。如下图: 潜艇生成坐标 public boolean isIsBoom() return isBoom; isIsBoom()方法用来判断潜艇是否爆炸(4)水雷类的实现游戏中水雷类bomb主要用来在屏幕中绘制出水雷的外观,并定义移动的方法,最重要的是在该类中定义了水雷和潜艇的碰撞检测方法,具体代码定义如下: public Bomb(Image bombImage, int x, i
19、nt y, int height) this.bombImage = bombImage; this.x = x; this.y = y; this.height = height; /初始化图片高度和宽度 this.imageHeight = bombImage.getHeight(); this.imageWidth = bombImage.getWidth();类的构造器bomb()中声明要显示的图像public void paint(Graphics g) g.drawImage(bombImage, x, y, Graphics.TOP | Graphics.LEFT); Paint
20、()方法用来绘制潜艇外观public void move() if (y height) y += dy; else /使炸弹不可见 水雷移动示意图 isDisplay = false;Move()方法定义水雷的移动判断水雷的纵坐标是否等于屏幕的高度,如果小于继续向下单位移动,否则水雷消失。 public boolean collidesWith(Submarine submarine) /炸弹中心点的坐标 int bx = x + imageWidth / 2; int by = y + imageHeight / 2; /潜艇中心点的坐标 int sx = submarine.getX()
21、 + submarine.getImageWidth() / 2; int sy = submarine.getY() + submarine.getImageHeight() / 2; /判断中心点之间的距离 if (Math.abs(bx - sx) (imageWidth + submarine.getImageWidth() / 2) & (Math.abs(by - sy) (imageHeight + submarine.getImageHeight() / 2) return true; else return false; collidesWith()方法用来碰撞检测判断两个对
22、象中心点之间的距离,水雷中心点A(x1,y1)的坐标是(水雷的横坐标+图片宽度的一半,水雷的纵坐标+图片高度的一半),潜艇中心点B(x2,y2)的坐标是(潜艇的横坐标+图片宽度的一半,潜艇的纵坐标+图片高度的一半)。如果|x1-x2|水雷图片宽度+潜艇图片宽度的一半,则水雷图片在如图A标明的区域移动。如果|y1-y2|水雷图片高度+潜艇图片高度的一半,则水雷图片在如图B标明的区域移动。两个条件同时成立,在这个区域内水雷与潜艇就是相互碰撞的,图C所示: public void handlecollidesWith(Submarine submarine) isDisplay = false;/设
23、置炸弹不可见 submarine.setIsBoom(true); /潜艇爆炸 handlecollidesWith()方法用来进行碰撞处理 移动区域A图 5-5 中心点坐标位置 移动区域B 移动区域C(5)音乐类的实现 该类的主要功能是使用MIDP1.0 Media API 播放背景音乐,具体代码如下: public void playCityMusic() springPlayer = null; flowerPlayer = null; cityPlayer = createPlayer(/city.mid, audio/midi); startPlayer(cityPlayer);playCityMusic()方法用来播
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1