科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件J2ME 2D小游戏入门之加入子弹群

J2ME 2D小游戏入门之加入子弹群

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

飞机类游戏中子弹是必不可少的,他们数量很多且充斥着整个屏幕,这些随机或者有着一定AI的小物体.

作者:朱晓华 来源:J2ME开发网 2007年12月28日

关键字: J2ME 2D 游戏 子弹群

  • 评论
  • 分享微博
  • 分享邮件
飞机类游戏中子弹是必不可少的,他们数量很多且充斥着整个屏幕,这些随机或者有着一定AI的小物体,实现起来不是总那么容易,有时候你不得不考虑很多和效能有关的问题。我们之前定义了GameObject,很大程度上就是为了方便的重用Sprite,因为我们有很多的子弹,不可能没增加一个子弹都是一个Sprite,我需要共享同一个Sprite。我们通过继承GameObject来实现。

  下面分析一下这个子弹类:

  它将继承自GameObject;

  记录子弹的个数;

   一个子弹的状态数组,记录各个子弹的类型type,位置x,y,速度vx,vy,是否存活alive等等。
   
  初始化子弹

  一个绘制方法,将子弹画到屏幕上。

  一个碰撞检测方法。

  好了先这样吧,以下是我们子弹类的定义,注意这种思想——重用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;//分为上下左右四种
 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 int[bulletstotal][6];
  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号子弹
  bullets[i][0] = (rnd.nextInt() & 0x7fffffff) % 4; //type
  bullets[i][5] = 1; //alive 1表示存活, 0表示死去
  switch (bullets[i][0]) {
   case BULLET_TYPE_LEFT:
    bullets[i][1] = -5;
    bullets[i][2] = (rnd.nextInt() & 0x7fffffff) % height;
    bullets[i][3] = (rnd.nextInt() & 0x7fffffff) % 3 + 1; //vx
    bullets[i][4] = (rnd.nextInt()) % 3; //vy
    break;
   case BULLET_TYPE_RIGHT:
    bullets[i][1] = width + 5;
    bullets[i][2] = (rnd.nextInt() & 0x7fffffff) % height;
    bullets[i][3] = ( (rnd.nextInt() & 0x7fffffff) % 3 + 1) * -1; //vx
    bullets[i][4] = (rnd.nextInt()) % 3; //vy
    break;
   case BULLET_TYPE_TOP:
    bullets[i][1] = (rnd.nextInt() & 0x7fffffff) % width;
    bullets[i][2] = -5;
    bullets[i][3] = (rnd.nextInt()) % 3; //vx
    bullets[i][4] = (rnd.nextInt() & 0x7fffffff) % 3 + 1; //vy
    break;
   case BULLET_TYPE_BOTTOM:
    bullets[i][1] = (rnd.nextInt() & 0x7fffffff) % width;
    bullets[i][2] = height + 5;
    bullets[i][3] = (rnd.nextInt()) % 3; //vx
    bullets[i][4] = ( (rnd.nextInt() & 0x7fffffff) % 3 + 1) * -1; //vy
    break;
   }
  }
  public void updata(int i){//根据速度更新i子弹下一桢的位置,碰壁反弹
   bullets[i][1]+=bullets[i][3];
   bullets[i][2]+=bullets[i][4];
   if(bullets[i][1]<-5 || bullets[i][1]>width+5){
    bullets[i][3]*=-1;
   }
   if(bullets[i][2]<-5 || bullets[i][2]>height+5){
    bullets[i][4]*=-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 < bullets.length; i++) {
    if(bullets[i][5]==0){//死去的子弹不绘画
     continue;
    }
   sprite.setPosition(bullets[i][1],bullets[i][2]); //更新位置
   sprite.paint(g);
  }
 }
 public void refreshBullets(Sprite planesprite, boolean needcollision){//刷新字典数组的状态,并作碰撞处理
  for (int i = 0; i < bullets.length; i++) {
   if(bullets[i][5]==0){ //死去的子弹不更新
    continue;
  }
  if(needcollision){//如果需要碰撞检测
   if (isCollision(planesprite, i, 10)) {//如果碰撞,进行处理
    //System.out.println("collision ");
    Navigate.mc.gameover = true;
    Navigate.mc.explosion.sprite.setPosition(bullets[i][1] - 16,bullets[i][2] - 16);
    bullets[i][5] = 0;//杀死碰撞的子弹
    continue;
   }
  }
  updata(i);//更新状态
 }
}

private boolean isCollision(Sprite sprite,int 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=bullets[i][1]+3;
 int bulletYCenter=bullets[i][2]+3;
 if(Math.abs(planeXCenter-bulletXCenter) < range){
  if (Math.abs(planeYCenter - bulletYCenter )< range) {
   result = true;
  }
 }
 return result;
}

private void updataspritepos(int i){//将sprite更新到i字弹的位置

sprite.setPosition(bullets[i][1],bullets[i][2]);

}

public void killbullets(Sprite planesprite,int range){杀死一定区域内的子弹

 for (int i = 0; i < bullets.length; i++) {
  if(bullets[i][5]!=0){//alive bullets
   if(isCollision(planesprite, i, range)){
    bullets[i][5]=0;
    initBullet(i);
   }
  }
 }
}

}
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章