飞机类游戏中子弹是必不可少的,他们数量很多且充斥着整..._第1页
飞机类游戏中子弹是必不可少的,他们数量很多且充斥着整..._第2页
飞机类游戏中子弹是必不可少的,他们数量很多且充斥着整..._第3页
飞机类游戏中子弹是必不可少的,他们数量很多且充斥着整..._第4页
飞机类游戏中子弹是必不可少的,他们数量很多且充斥着整..._第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

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

文档简介

1、飞机类游戏中子弹是必不可少的,他们数量很多且充斥着整个屏幕,这些随机或者有着一定AI的小物体,实现起来不是总那么容易,有时候你不得不考虑很多和效能有关的问题。我们之前定义了GameObject,很大程度上就是为了方便的重用Sprite,因为我们有很多的子弹,不可能没增加一个子弹都是一个Sprite,我需要共享同一个Sprite。我们通过继承GameObject来实现。 下面分析一下这个子弹类: 它将继承自GameObject; 记录子弹的个数; 一个子弹的状态数组,记录各个子弹的类型type,位置x,y,速度vx,vy,是否存活alive等等。 初始化子弹 一个绘制方法,将子弹画到屏幕上。 一

2、个碰撞检测方法。 好了先这样吧,以下是我们子弹类的定义,注意这种思想重用Sprite,这很重要。(这里参考了tony的很多设计) public class Bullets extends GameObject private int bullets;/子弹状态数组 private int bulletstotal;/数组的length private Random rnd;/随机数 public static final int BULLET_TYPE_LEFT=0;/子弹初始化的位置类型 public static final int BULLET_TYPE_RIGHT=1;/分为上下左右四

3、种 public static final int BULLET_TYPE_TOP=2; public static final int BULLET_TYPE_BOTTOM=3; private int width,height;/屏幕的高和宽,用于随机子弹位置 public Bullets(Image img,int picwidth,int picheight,int bulletstotal,int width,int height) super(img,picwidth,picheight); this.bulletstotal=bulletstotal; bullets=new i

4、ntbulletstotal6; rnd=new Random(); this.width=width; this.height=height; public void initBullets()/初始化子弹状态数组 for (int i = 0; i < bullets.length; i+) initBullet(i); private void initBullet(int i) /初始化index号子弹 bulletsi0 = (rnd.nextInt() & 0x7fffffff) % 4; /type bulletsi5 = 1; /alive 1表示存活, 0表示死

5、去 switch (bulletsi0) case BULLET_TYPE_LEFT: bulletsi1 = -5; bulletsi2 = (rnd.nextInt() & 0x7fffffff) % height; bulletsi3 = (rnd.nextInt() & 0x7fffffff) % 3 + 1; /vx bulletsi4 = (rnd.nextInt() % 3; /vy break; case BULLET_TYPE_RIGHT: bulletsi1 = width + 5; bulletsi2 = (rnd.nextInt() & 0x7f

6、ffffff) % height; bulletsi3 = ( (rnd.nextInt() & 0x7fffffff) % 3 + 1) * -1; /vx bulletsi4 = (rnd.nextInt() % 3; /vy break; case BULLET_TYPE_TOP: bulletsi1 = (rnd.nextInt() & 0x7fffffff) % width; bulletsi2 = -5; bulletsi3 = (rnd.nextInt() % 3; /vx bulletsi4 = (rnd.nextInt() & 0x7fffffff)

7、% 3 + 1; /vy break; case BULLET_TYPE_BOTTOM: bulletsi1 = (rnd.nextInt() & 0x7fffffff) % width; bulletsi2 = height + 5; bulletsi3 = (rnd.nextInt() % 3; /vx bulletsi4 = ( (rnd.nextInt() & 0x7fffffff) % 3 + 1) * -1; /vy break; public void updata(int i)/根据速度更新i子弹下一桢的位置,碰壁反弹 bulletsi1+=bulletsi3;

8、 bulletsi2+=bulletsi4; if(bulletsi1<-5 | bulletsi1>width+5) bulletsi3*=-1; if(bulletsi2<-5 | bulletsi2>height+5) bulletsi4*=-1; private void paint(Graphics g,int i)/绘画出第i个子弹 updataspritepos(i);/更新位置 sprite.paint(g);/绘画Sprtie public void paint(Graphics g) /绘画整个子弹组 for (int i = 0; i < b

9、ullets.length; i+) if(bulletsi5=0)/死去的子弹不绘画 continue; sprite.setPosition(bulletsi1,bulletsi2); /更新位置 sprite.paint(g); public void refreshBullets(Sprite planesprite, boolean needcollision)/刷新字典数组的状态,并作碰撞处理 for (int i = 0; i < bullets.length; i+) if(bulletsi5=0) /死去的子弹不更新 continue; if(needcollision

10、)/如果需要碰撞检测 if (isCollision(planesprite, i, 10) /如果碰撞,进行处理 /System.out.println("collision "); Navigate.mc.gameover = true; Navigate.mc.explosion.sprite.setPosition(bulletsi1 - 16, bulletsi2 - 16); bulletsi5 = 0;/杀死碰撞的子弹 continue; updata(i);/更新状态 private boolean isCollision(Sprite sprite,int

11、 i,int range) /判断是否碰撞 /updataspritepos(i); /return sprite.collidesWith(this.sprite,true); boolean result=false; int planeXCenter=sprite.getX()+12; int planeYCenter=sprite.getY()+12; int bulletXCenter=bulletsi1+3; int bulletYCenter=bulletsi2+3; if(Math.abs(planeXCenter-bulletXCenter) < range) if (

12、Math.abs(planeYCenter - bulletYCenter )< range) result = true; return result; private void updataspritepos(int i)/将sprite更新到i字弹的位置 sprite.setPosition(bulletsi1,bulletsi2); /* no use now public void resetDeadBullet() for (int i = 0; i < bullets.length; i+) if(bulletsi5=0)/dead bullet initBullet

13、(i); */ public void killbullets(Sprite planesprite,int range)杀死一定区域内的子弹 for (int i = 0; i < bullets.length; i+) if(bulletsi5!=0)/alive bullets if(isCollision(planesprite, i, range) bulletsi5=0; initBullet(i); 子弹如何表示? 首先我们用一个二维数组来记录子弹的信息: bulletsi0表示子弹的类型,有上、下、左、右四种,分别表示子弹飞入屏幕前的四种位置; bulletsi1表示子弹

14、的x坐标; bulletsi2表示子弹的y坐标 bulletsi3表示子弹的x方向速度; bulletsi4表示子弹的y方向速度; bulletsi5表示子弹的存活状态; 子弹如何初始化? 我们首先写了一个初始化单个子弹的方法,然后便利数组调用initBullet (i);来更新整个状态数组。 子弹如何绘制? 我们首先写了一个绘制单个子弹的方法,然后便利数组调用paint(g,i);来绘制整个状态数组。 子弹如何碰撞? 有很多种方法,其中sprite本身就提供了边框碰撞检测和基于像素的碰撞检测。前者不太适合我们的游戏,我们的飞机是不规则物体,且飞行游戏对碰撞比较敏感;而后者的效率又得不到我们的

15、信赖,所以我们是用一种半径检测,把飞机近似的看成圆,选取恰当的半径,Math.abs(planeXCenter-bulletXCenter) < range则表明碰撞。 碰撞看似简单,其实是很复杂的问题,值得庆幸的是,二维碰撞相比三维碰撞简单得多。一个小技巧是,宁可让膨胀检测半径变小也不要他变得大漏掉检测,总比误检测要好得多。 子弹更新? 我们利用refreshBullets进行更新,这是主要逻辑部分。这个方法负责便利数组检测碰撞,如果碰撞就将处于碰撞位置的子弹杀死,并作相应的处理,这里是结束游戏并爆炸飞机;否则更新子弹的位置。 我们只是线性的遍历整个的数组,进行碰撞检测,之后是更新位置

16、;但是这样做有一个前提,就是碰撞检测简单而且处理部分也很简单:在这个游戏中,碰撞检测只是子弹群和飞机的检测,碰撞检测在游戏结束后就不执行了(通过控制boolean needcollision);而处理更是简单了一些直接结束了游戏。如果不是如此,比如处理后并不是简单的结束游戏,我们就不得不设计的复杂一些。可能就不是将碰撞简单的以飞机为中心了。我们需要设计好游戏事件,设计好碰撞系统。 如果碰撞本身比较复杂,或者子弹数量,种类增加时,我们线性的遍历数组就不能总是对所有的子弹都检测,可能屏幕需要分区,不处于一个区域的单位不检测。 总之当你想想你的1934时,将不在是想象着子弹,飞机什么的,你要思考一个系统。 总结一下子弹类的公共接口: n Bullets(Image img,int picwidth,int picheight,int bulletstotal,int width,int height)构造函数 n public vo

温馨提示

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

评论

0/150

提交评论