欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实战打飞机游戏之子弹生成与碰撞以及爆炸效果(5)

程序员文章站 2024-03-06 12:24:07
android实战打飞机游戏子弹生成,新建子弹类 public class bullet { // 子弹图片资源 public bitmap bmpbul...

android实战打飞机游戏子弹生成,新建子弹类

public class bullet {
 // 子弹图片资源
 public bitmap bmpbullet;
 // 子弹的坐标
 public int bulletx, bullety;
 // 子弹的速度
 public int speed;
 // 子弹的种类以及常量
 public int bullettype;
 // 主角的
 public static final int bullet_player = -1;
 // 鸭子的
 public static final int bullet_duck = 1;
 // 苍蝇的
 public static final int bullet_fly = 2;
 // boss的
 public static final int bullet_boss = 3;
 // 子弹是否超屏, 优化处理
 public boolean isdead;

 // boss疯狂状态下子弹相关成员变量
 private int dir;// 当前boss子弹方向
 // 8方向常量
 public static final int dir_up = -1;
 public static final int dir_down = 2;
 public static final int dir_left = 3;
 public static final int dir_right = 4;
 public static final int dir_up_left = 5;
 public static final int dir_up_right = 6;
 public static final int dir_down_left = 7;
 public static final int dir_down_right = 8;

 // 子弹当前方向
 public bullet(bitmap bmpbullet, int bulletx, int bullety, int bullettype) {
  this.bmpbullet = bmpbullet;
  this.bulletx = bulletx;
  this.bullety = bullety;
  this.bullettype = bullettype;
  // 不同的子弹类型速度不一
  switch (bullettype) {
  case bullet_player:
   speed = 4;
   break;
  case bullet_duck:
   speed = 3;
   break;
  case bullet_fly:
   speed = 4;
   break;
  case bullet_boss:
   speed = 5;
   break;
  }
 }

 public void draw(canvas canvas, paint paint) {
  canvas.drawbitmap(bmpbullet, bulletx, bullety, paint);
 }

 // 子弹的逻辑
 public void logic() {
  // 不同的子弹类型逻辑不一
  // 主角的子弹垂直向上运动
  switch (bullettype) {
  case bullet_player:
   bullety -= speed;
   if (bullety < -50) {
    isdead = true;
   }
   break;
  // 鸭子和苍蝇的子弹都是垂直下落运动
  case bullet_duck:
  case bullet_fly:
   bullety += speed;
   if (bullety > mysurfaceview.screenh) {
    isdead = true;
   }
   break;
  case bullet_boss:
   // boss疯狂状态下的子弹逻辑待实现
   // 边界处理
   if (bullety > mysurfaceview.screenh || bullety <= -40
     || bulletx > mysurfaceview.screenw || bulletx <= -40) {
    isdead = true;
   }
   break;
  }
 }

}

在在mysurfacview里面调用 生成子弹主角的和自己的

package com.gsf;

import java.util.random;
import java.util.vector;

import android.content.context;
import android.content.res.resources;
import android.graphics.bitmap;
import android.graphics.bitmapfactory;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.view.keyevent;
import android.view.motionevent;
import android.view.surfaceholder;
import android.view.surfaceholder.callback;
import android.view.surfaceview;

public class mysurfaceview extends surfaceview implements callback, runnable {
 private surfaceholder sfh;
 private paint paint;
 private thread th;
 private boolean flag;
 private canvas canvas;

 // 1 定义游戏状态常量
 public static final int game_menu = 0;// 游戏菜单
 public static final int gameing = 1;// 游戏中
 public static final int game_win = 2;// 游戏胜利
 public static final int game_lost = 3;// 游戏失败
 public static final int game_pause = -1;// 游戏菜单
 // 当前游戏状态(默认初始在游戏菜单界面)
 public static int gamestate = game_menu;
 // 声明一个resources实例便于加载图片
 private resources res = this.getresources();
 // 声明游戏需要用到的图片资源(图片声明)
 private bitmap bmpbackground;// 游戏背景
 private bitmap bmpboom;// 爆炸效果
 private bitmap bmpboosboom;// boos爆炸效果
 private bitmap bmpbutton;// 游戏开始按钮
 private bitmap bmpbuttonpress;// 游戏开始按钮被点击
 private bitmap bmpenemyduck;// 怪物鸭子
 private bitmap bmpenemyfly;// 怪物苍蝇
 private bitmap bmpenemyboos;// 怪物猪头boos
 private bitmap bmpgamewin;// 游戏胜利背景
 private bitmap bmpgamelost;// 游戏失败背景
 private bitmap bmpplayer;// 游戏主角飞机
 private bitmap bmpplayerhp;// 主角飞机血量
 private bitmap bmpmenu;// 菜单背景
 public static bitmap bmpbullet;// 子弹
 public static bitmap bmpenemybullet;// 敌机子弹
 public static bitmap bmpbossbullet;// boss子弹
 public static int screenw;
 public static int screenh;

 // 声明一个敌机容器
 private vector<enemy> vcenemy;
 // 每次生成敌机的时间(毫秒)
 private int createenemytime = 50;
 private int count;// 计数器
 // 敌人数组:1和2表示敌机的种类,-1表示boss
 // 二维数组的每一维都是一组怪物
 private int enemyarray[][] = { { 1, 2 }, { 1, 1 }, { 1, 3, 1, 2 },
   { 1, 2 }, { 2, 3 }, { 3, 1, 3 }, { 2, 2 }, { 1, 2 }, { 2, 2 },
   { 1, 3, 1, 1 }, { 2, 1 }, { 1, 3 }, { 2, 1 }, { -1 } };
 // 当前取出一维数组的下标
 private int enemyarrayindex;
 // 是否出现boss标识位
 private boolean isboss;
 // 随机库,为创建的敌机赋予随即坐标
 private random random;

 //
 private gamemenu gamemenu;
 private gamebg gamebg;

 private player player;

 // 敌机子弹容器
 private vector<bullet> vcbullet;
 // 添加子弹的计数器
 private int countenemybullet;
 // 主角子弹容器
 private vector<bullet> vcbulletplayer;
 // 添加子弹的计数器
 private int countplayerbullet;

 /**
  * surfaceview初始化函数
  */
 public mysurfaceview(context context) {
  super(context);
  sfh = this.getholder();
  sfh.addcallback(this);
  paint = new paint();
  paint.setcolor(color.white);
  paint.setantialias(true);
  setfocusable(true);
 }

 /**
  * surfaceview视图创建,响应此函数
  */
 @override
 public void surfacecreated(surfaceholder holder) {
  screenw = this.getwidth();
  screenh = this.getheight();
  initgame();
  flag = true;
  // 实例线程
  th = new thread(this);
  // 启动线程
  th.start();
 }

 /**
  * 加载游戏资源
  */
 private void initgame() {
  // 加载游戏资源
  bmpbackground = bitmapfactory
    .decoderesource(res, r.drawable.background);
  bmpboom = bitmapfactory.decoderesource(res, r.drawable.boom);
  bmpboosboom = bitmapfactory.decoderesource(res, r.drawable.boos_boom);
  bmpbutton = bitmapfactory.decoderesource(res, r.drawable.button);
  bmpbuttonpress = bitmapfactory.decoderesource(res,
    r.drawable.button_press);
  bmpenemyduck = bitmapfactory.decoderesource(res, r.drawable.enemy_duck);
  bmpenemyfly = bitmapfactory.decoderesource(res, r.drawable.enemy_fly);
  bmpenemyboos = bitmapfactory.decoderesource(res, r.drawable.enemy_pig);
  bmpgamewin = bitmapfactory.decoderesource(res, r.drawable.gamewin);
  bmpgamelost = bitmapfactory.decoderesource(res, r.drawable.gamelost);
  bmpplayer = bitmapfactory.decoderesource(res, r.drawable.player);
  bmpplayerhp = bitmapfactory.decoderesource(res, r.drawable.hp);
  bmpmenu = bitmapfactory.decoderesource(res, r.drawable.menu);
  bmpbullet = bitmapfactory.decoderesource(res, r.drawable.bullet);
  bmpenemybullet = bitmapfactory.decoderesource(res,
    r.drawable.bullet_enemy);
  bmpbossbullet = bitmapfactory
    .decoderesource(res, r.drawable.boosbullet);

  // 菜单类实例化
  gamemenu = new gamemenu(bmpmenu, bmpbutton, bmpbuttonpress);
  // 实例游戏背景
  gamebg = new gamebg(bmpbackground);
  // 实例主角
  player = new player(bmpplayer, bmpplayerhp);
  //敌机子弹容器实例
  vcbullet = new vector<bullet>();
  //主角子弹容器实例
  vcbulletplayer = new vector<bullet>();
  // 实例敌机容器
  vcenemy = new vector<enemy>();
  // 实例随机库
  random = new random();
 }

 /**
  * 游戏绘图
  */
 public void mydraw() {
  try {
   canvas = sfh.lockcanvas();
   if (canvas != null) {
    canvas.drawcolor(color.white);
    // 绘图函数根据游戏状态不同进行不同绘制

    switch (gamestate) {
    case game_menu:

     gamemenu.draw(canvas, paint);
     break;
    case gameing:
     gamebg.draw(canvas, paint);
     player.draw(canvas, paint);
     if (isboss == false) {
      // 敌机绘制
      for (int i = 0; i < vcenemy.size(); i++) {
       vcenemy.elementat(i).draw(canvas, paint);
      }
      //敌机子弹绘制
      for (int i = 0; i < vcbullet.size(); i++) {
       vcbullet.elementat(i).draw(canvas, paint);
      }

     } else {
      // boss 绘制

     }
     // 处理主角子弹绘制
     for (int i = 0; i < vcbulletplayer.size(); i++) {
      vcbulletplayer.elementat(i).draw(canvas, paint);
     }

     break;

    case game_win:

     break;
    case game_lost:

     break;
    case game_pause:

     break;
    default:
     break;
    }

   }
  } catch (exception e) {
   // todo: handle exception
  } finally {
   if (canvas != null)
    sfh.unlockcanvasandpost(canvas);
  }
 }

 /**
  * 触屏事件监听
  */
 @override
 public boolean ontouchevent(motionevent event) {
  switch (gamestate) {
  case game_menu:

   gamemenu.ontouchevent(event);
   break;
  case gameing:

   break;

  case game_win:

   break;
  case game_lost:

   break;
  case game_pause:

   break;
  }
  return true;
 }

 /**
  * 按键事件监听
  */
 @override
 public boolean onkeydown(int keycode, keyevent event) {
  switch (gamestate) {
  case game_menu:

   break;
  case gameing:
   player.onkeydown(keycode, event);
   break;

  case game_win:

   break;
  case game_lost:

   break;
  case game_pause:
   break;
  }
  return super.onkeydown(keycode, event);
 }

 @override
 public boolean onkeyup(int keycode, keyevent event) {
  switch (gamestate) {
  case game_menu:

   break;
  case gameing:
   player.onkeyup(keycode, event);
   break;

  case game_win:

   break;
  case game_lost:

   break;
  case game_pause:
   break;
  }
  return super.onkeyup(keycode, event);
 }

 /**
  * 游戏逻辑
  */
 private void logic() {
  switch (gamestate) {
  case game_menu:

   break;
  case gameing:
   gamebg.logic();
   player.logic();
   // 敌机逻辑
   if (isboss == false) {
    // 敌机逻辑
    for (int i = 0; i < vcenemy.size(); i++) {
     enemy en = vcenemy.elementat(i);
     // 因为容器不断添加敌机 ,那么对敌机isdead判定,
     // 如果已死亡那么就从容器中删除,对容器起到了优化作用;
     if (en.isdead) {
      vcenemy.removeelementat(i);
     } else {
      en.logic();
     }
    }
    // 生成敌机
    count++;
    if (count % createenemytime == 0) {
     for (int i = 0; i < enemyarray[enemyarrayindex].length; i++) {
      // 苍蝇
      if (enemyarray[enemyarrayindex][i] == 1) {
       int x = random.nextint(screenw - 100) + 50;
       vcenemy.addelement(new enemy(bmpenemyfly, 1, x, -50));
       // 鸭子左
      } else if (enemyarray[enemyarrayindex][i] == 2) {
       int y = random.nextint(20);
       vcenemy.addelement(new enemy(bmpenemyduck, 2, -50,
         y));
       // 鸭子右
      } else if (enemyarray[enemyarrayindex][i] == 3) {
       int y = random.nextint(20);
       vcenemy.addelement(new enemy(bmpenemyduck, 3,
         screenw + 50, y));
      }
     }
     // 这里判断下一组是否为最后一组(boss)
     if (enemyarrayindex == enemyarray.length - 1) {
      isboss = true;
     } else {
      enemyarrayindex++;
     }
    }

    // 每2秒添加一个敌机子弹
    countenemybullet++;
    if (countenemybullet % 40 == 0) {
     for (int i = 0; i < vcenemy.size(); i++) {
      enemy en = vcenemy.elementat(i);
      // 不同类型敌机不同的子弹运行轨迹
      int bullettype = 0;
      switch (en.type) {
      // 苍蝇
      case enemy.type_fly:
       bullettype = bullet.bullet_fly;
       break;
      // 鸭子
      case enemy.type_duckl:
      case enemy.type_duckr:
       bullettype = bullet.bullet_duck;
       break;
      }
      vcbullet.add(new bullet(bmpenemybullet, en.x + 10,
        en.y + 20, bullettype));
     }
    }
    // 处理敌机子弹逻辑
    for (int i = 0; i < vcbullet.size(); i++) {
     bullet b = vcbullet.elementat(i);
     if (b.isdead) {
      vcbullet.removeelement(b);
     } else {
      b.logic();
     }
    }

    //每1秒添加一个主角子弹
    countplayerbullet++;
    if (countplayerbullet % 20 == 0) {
     vcbulletplayer.add(new bullet(bmpbullet, player.x + 15, player.y - 20, bullet.bullet_player));
    }

    // 处理敌机与主角的碰撞
    for (int i = 0; i < vcenemy.size(); i++) {
     if (player.iscollsionwith(vcenemy.elementat(i))) {
      // 发生碰撞,主角血量-1
      player.setplayerhp(player.getplayerhp() - 1);
      // 当主角血量小于0,判定游戏失败
      if (player.getplayerhp() <= -1) {
       gamestate = game_lost;
      }
     }
    }

    //处理主角子弹逻辑
    for (int i = 0; i < vcbulletplayer.size(); i++) {
     bullet b = vcbulletplayer.elementat(i);
     if (b.isdead) {
      vcbulletplayer.removeelement(b);
     } else {
      b.logic();
     }
    }
   }
   break;

  case game_win:

   break;
  case game_lost:

   break;
  case game_pause:
   break;
  }

 }

 @override
 public void run() {
  while (flag) {
   long start = system.currenttimemillis();
   mydraw();
   logic();
   long end = system.currenttimemillis();
   try {
    if (end - start < 50) {
     thread.sleep(50 - (end - start));
    }
   } catch (interruptedexception e) {
    e.printstacktrace();
   }
  }
 }

 /**
  * surfaceview视图状态发生改变,响应此函数
  */
 @override
 public void surfacechanged(surfaceholder holder, int format, int width,
   int height) {
 }

 /**
  * surfaceview视图消亡时,响应此函数
  */
 @override
 public void surfacedestroyed(surfaceholder holder) {
  flag = false;
 }
}

现在子弹碰撞主角 并没有发生事情 需要子弹和主角的碰撞检测

//修改player类 添加碰撞检测
 // // 判断碰撞(主角与敌机子弹)
 public boolean iscollsionwith(bullet bullet) {
  // 是否处于无敌时间
  if (iscollision == false) {
   int x2 = bullet.bulletx;
   int y2 = bullet.bullety;
   int w2 = bullet.bmpbullet.getwidth();
   int h2 = bullet.bmpbullet.getheight();
   if (x >= x2 && x >= x2 + w2) {
    return false;
   } else if (x <= x2 && x + bmpplayer.getwidth() <= x2) {
    return false;
   } else if (y >= y2 && y >= y2 + h2) {
    return false;
   } else if (y <= y2 && y + bmpplayer.getheight() <= y2) {
    return false;
   }
   // 碰撞即进入无敌状态
   iscollision = true;
   return true;
   // 处于无敌状态,无视碰撞
  } else {
   return false;
  }
 }

 在主界面 mysrufaceview 的逻辑函数中添加 主角和敌机子弹的碰撞

 //处理敌机子弹与主角碰撞
    for (int i = 0; i < vcbullet.size(); i++) {
     if (player.iscollsionwith(vcbullet.elementat(i))) {
      //发生碰撞,主角血量-1
      player.setplayerhp(player.getplayerhp() - 1);
      //当主角血量小于0,判定游戏失败
      if (player.getplayerhp() <= -1) {
       gamestate = game_lost;
      }
     }
    }

当然 主角的子弹碰撞了敌机 也需要进行碰撞检测 修改 敌机类 enemy

 //判断碰撞(敌机与主角子弹碰撞)
 public boolean iscollsionwith(bullet bullet) {
  int x2 = bullet.bulletx;
  int y2 = bullet.bullety;
  int w2 = bullet.bmpbullet.getwidth();
  int h2 = bullet.bmpbullet.getheight();
  if (x >= x2 && x >= x2 + w2) {
   return false;
  } else if (x <= x2 && x + framew <= x2) {
   return false;
  } else if (y >= y2 && y >= y2 + h2) {
   return false;
  } else if (y <= y2 && y + frameh <= y2) {
   return false;
  }
  //发生碰撞,让其死亡
  isdead = true;
  return true;
 }

在主视图中添加逻辑 主角子弹和敌机碰撞的逻辑

 //处理主角子弹与敌机碰撞
    for (int i = 0; i < vcbulletplayer.size(); i++) {
     //取出主角子弹容器的每个元素
     bullet blplayer = vcbulletplayer.elementat(i);
     for (int j = 0; j < vcenemy.size(); j++) {
      //添加爆炸效果 待完成
     }
    }

Android实战打飞机游戏之子弹生成与碰撞以及爆炸效果(5)

上面完成 的效果图

下面完成爆炸的效果

新建一个爆炸类 boom

/**
 * 瞬间爆炸 类
 * @author liuml
 * @time 2016-6-1 上午11:32:56
 */
public class boom {
 //爆炸效果资源图
 private bitmap bmpboom;
 //爆炸效果的位置坐标
 private int boomx, boomy;
 //爆炸动画播放当前的帧下标
 private int cureentframeindex;
 //爆炸效果的总帧数
 private int totleframe;
 //每帧的宽高
 private int framew, frameh;
 //是否播放完毕,优化处理
 public boolean playend;

 //爆炸效果的构造函数
 public boom(bitmap bmpboom, int x, int y, int totleframe) {
  this.bmpboom = bmpboom;
  this.boomx = x;
  this.boomy = y;
  this.totleframe = totleframe;
  framew = bmpboom.getwidth() / totleframe;
  frameh = bmpboom.getheight();
 }

 //爆炸效果绘制
 public void draw(canvas canvas, paint paint) {
  canvas.save();
  canvas.cliprect(boomx, boomy, boomx + framew, boomy + frameh);
  canvas.drawbitmap(bmpboom, boomx - cureentframeindex * framew, boomy, paint);
  canvas.restore();
 }

 //爆炸效果的逻辑
 public void logic() {
  if (cureentframeindex < totleframe) {
   cureentframeindex++;
  } else {
   playend = true;
  }
 }
}

下面就还是老套路了 在主界面 声明爆炸容器 然后绘制 然后是逻辑实现

 package com.gsf;

import java.util.random;
import java.util.vector;

import android.content.context;
import android.content.res.resources;
import android.graphics.bitmap;
import android.graphics.bitmapfactory;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.view.keyevent;
import android.view.motionevent;
import android.view.surfaceholder;
import android.view.surfaceholder.callback;
import android.view.surfaceview;

public class mysurfaceview extends surfaceview implements callback, runnable {
 private surfaceholder sfh;
 private paint paint;
 private thread th;
 private boolean flag;
 private canvas canvas;

 // 1 定义游戏状态常量
 public static final int game_menu = 0;// 游戏菜单
 public static final int gameing = 1;// 游戏中
 public static final int game_win = 2;// 游戏胜利
 public static final int game_lost = 3;// 游戏失败
 public static final int game_pause = -1;// 游戏菜单
 // 当前游戏状态(默认初始在游戏菜单界面)
 public static int gamestate = game_menu;
 // 声明一个resources实例便于加载图片
 private resources res = this.getresources();
 // 声明游戏需要用到的图片资源(图片声明)
 private bitmap bmpbackground;// 游戏背景
 private bitmap bmpboom;// 爆炸效果
 private bitmap bmpboosboom;// boos爆炸效果
 private bitmap bmpbutton;// 游戏开始按钮
 private bitmap bmpbuttonpress;// 游戏开始按钮被点击
 private bitmap bmpenemyduck;// 怪物鸭子
 private bitmap bmpenemyfly;// 怪物苍蝇
 private bitmap bmpenemyboos;// 怪物猪头boos
 private bitmap bmpgamewin;// 游戏胜利背景
 private bitmap bmpgamelost;// 游戏失败背景
 private bitmap bmpplayer;// 游戏主角飞机
 private bitmap bmpplayerhp;// 主角飞机血量
 private bitmap bmpmenu;// 菜单背景
 public static bitmap bmpbullet;// 子弹
 public static bitmap bmpenemybullet;// 敌机子弹
 public static bitmap bmpbossbullet;// boss子弹
 public static int screenw;
 public static int screenh;

 // 声明一个敌机容器
 private vector<enemy> vcenemy;
 // 每次生成敌机的时间(毫秒)
 private int createenemytime = 50;
 private int count;// 计数器
 // 敌人数组:1和2表示敌机的种类,-1表示boss
 // 二维数组的每一维都是一组怪物
 private int enemyarray[][] = { { 1, 2 }, { 1, 1 }, { 1, 3, 1, 2 },
   { 1, 2 }, { 2, 3 }, { 3, 1, 3 }, { 2, 2 }, { 1, 2 }, { 2, 2 },
   { 1, 3, 1, 1 }, { 2, 1 }, { 1, 3 }, { 2, 1 }, { -1 } };
 // 当前取出一维数组的下标
 private int enemyarrayindex;
 // 是否出现boss标识位
 private boolean isboss;
 // 随机库,为创建的敌机赋予随即坐标
 private random random;

 //
 private gamemenu gamemenu;
 private gamebg gamebg;

 private player player;

 // 敌机子弹容器
 private vector<bullet> vcbullet;
 // 添加子弹的计数器
 private int countenemybullet;
 // 主角子弹容器
 private vector<bullet> vcbulletplayer;
 // 添加子弹的计数器
 private int countplayerbullet;

 //爆炸效果容器
 private vector<boom> vcboom;

 /**
  * surfaceview初始化函数
  */
 public mysurfaceview(context context) {
  super(context);
  sfh = this.getholder();
  sfh.addcallback(this);
  paint = new paint();
  paint.setcolor(color.white);
  paint.setantialias(true);
  setfocusable(true);
 }

 /**
  * surfaceview视图创建,响应此函数
  */
 @override
 public void surfacecreated(surfaceholder holder) {
  screenw = this.getwidth();
  screenh = this.getheight();
  initgame();
  flag = true;
  // 实例线程
  th = new thread(this);
  // 启动线程
  th.start();
 }

 /**
  * 加载游戏资源
  */
 private void initgame() {
  // 加载游戏资源
  bmpbackground = bitmapfactory
    .decoderesource(res, r.drawable.background);
  bmpboom = bitmapfactory.decoderesource(res, r.drawable.boom);
  bmpboosboom = bitmapfactory.decoderesource(res, r.drawable.boos_boom);
  bmpbutton = bitmapfactory.decoderesource(res, r.drawable.button);
  bmpbuttonpress = bitmapfactory.decoderesource(res,
    r.drawable.button_press);
  bmpenemyduck = bitmapfactory.decoderesource(res, r.drawable.enemy_duck);
  bmpenemyfly = bitmapfactory.decoderesource(res, r.drawable.enemy_fly);
  bmpenemyboos = bitmapfactory.decoderesource(res, r.drawable.enemy_pig);
  bmpgamewin = bitmapfactory.decoderesource(res, r.drawable.gamewin);
  bmpgamelost = bitmapfactory.decoderesource(res, r.drawable.gamelost);
  bmpplayer = bitmapfactory.decoderesource(res, r.drawable.player);
  bmpplayerhp = bitmapfactory.decoderesource(res, r.drawable.hp);
  bmpmenu = bitmapfactory.decoderesource(res, r.drawable.menu);
  bmpbullet = bitmapfactory.decoderesource(res, r.drawable.bullet);
  bmpenemybullet = bitmapfactory.decoderesource(res,
    r.drawable.bullet_enemy);
  bmpbossbullet = bitmapfactory
    .decoderesource(res, r.drawable.boosbullet);

  // 菜单类实例化
  gamemenu = new gamemenu(bmpmenu, bmpbutton, bmpbuttonpress);
  // 实例游戏背景
  gamebg = new gamebg(bmpbackground);
  // 实例主角
  player = new player(bmpplayer, bmpplayerhp);
  //敌机子弹容器实例
  vcbullet = new vector<bullet>();
  //主角子弹容器实例
  vcbulletplayer = new vector<bullet>();
  // 实例敌机容器
  vcenemy = new vector<enemy>();
  // 实例随机库
  random = new random();
  //爆炸效果容器实例
  vcboom = new vector<boom>();
 }

 /**
  * 游戏绘图
  */
 public void mydraw() {
  try {
   canvas = sfh.lockcanvas();
   if (canvas != null) {
    canvas.drawcolor(color.white);
    // 绘图函数根据游戏状态不同进行不同绘制

    switch (gamestate) {
    case game_menu:

     gamemenu.draw(canvas, paint);
     break;
    case gameing:
     gamebg.draw(canvas, paint);
     player.draw(canvas, paint);
     if (isboss == false) {
      // 敌机绘制
      for (int i = 0; i < vcenemy.size(); i++) {
       vcenemy.elementat(i).draw(canvas, paint);
      }
      //敌机子弹绘制
      for (int i = 0; i < vcbullet.size(); i++) {
       vcbullet.elementat(i).draw(canvas, paint);
      }
      //爆炸效果绘制
      for (int i = 0; i < vcboom.size(); i++) {
       vcboom.elementat(i).draw(canvas, paint);
      }
     } else {
      // boss 绘制

     }
     // 处理主角子弹绘制
     for (int i = 0; i < vcbulletplayer.size(); i++) {
      vcbulletplayer.elementat(i).draw(canvas, paint);
     }

     break;

    case game_win:

     break;
    case game_lost:

     break;
    case game_pause:

     break;
    default:
     break;
    }

   }
  } catch (exception e) {
   // todo: handle exception
  } finally {
   if (canvas != null)
    sfh.unlockcanvasandpost(canvas);
  }
 }

 /**
  * 触屏事件监听
  */
 @override
 public boolean ontouchevent(motionevent event) {
  switch (gamestate) {
  case game_menu:

   gamemenu.ontouchevent(event);
   break;
  case gameing:

   break;

  case game_win:

   break;
  case game_lost:

   break;
  case game_pause:

   break;
  }
  return true;
 }

 /**
  * 按键事件监听
  */
 @override
 public boolean onkeydown(int keycode, keyevent event) {
  switch (gamestate) {
  case game_menu:

   break;
  case gameing:
   player.onkeydown(keycode, event);
   break;

  case game_win:

   break;
  case game_lost:

   break;
  case game_pause:
   break;
  }
  return super.onkeydown(keycode, event);
 }

 @override
 public boolean onkeyup(int keycode, keyevent event) {
  switch (gamestate) {
  case game_menu:

   break;
  case gameing:
   player.onkeyup(keycode, event);
   break;

  case game_win:

   break;
  case game_lost:

   break;
  case game_pause:
   break;
  }
  return super.onkeyup(keycode, event);
 }

 /**
  * 游戏逻辑
  */
 private void logic() {
  switch (gamestate) {
  case game_menu:

   break;
  case gameing:
   gamebg.logic();
   player.logic();
   // 敌机逻辑
   if (isboss == false) {
    // 敌机逻辑
    for (int i = 0; i < vcenemy.size(); i++) {
     enemy en = vcenemy.elementat(i);
     // 因为容器不断添加敌机 ,那么对敌机isdead判定,
     // 如果已死亡那么就从容器中删除,对容器起到了优化作用;
     if (en.isdead) {
      vcenemy.removeelementat(i);
     } else {
      en.logic();
     }
    }
    // 生成敌机
    count++;
    if (count % createenemytime == 0) {
     for (int i = 0; i < enemyarray[enemyarrayindex].length; i++) {
      // 苍蝇
      if (enemyarray[enemyarrayindex][i] == 1) {
       int x = random.nextint(screenw - 100) + 50;
       vcenemy.addelement(new enemy(bmpenemyfly, 1, x, -50));
       // 鸭子左
      } else if (enemyarray[enemyarrayindex][i] == 2) {
       int y = random.nextint(20);
       vcenemy.addelement(new enemy(bmpenemyduck, 2, -50,
         y));
       // 鸭子右
      } else if (enemyarray[enemyarrayindex][i] == 3) {
       int y = random.nextint(20);
       vcenemy.addelement(new enemy(bmpenemyduck, 3,
         screenw + 50, y));
      }
     }
     // 这里判断下一组是否为最后一组(boss)
     if (enemyarrayindex == enemyarray.length - 1) {
      isboss = true;
     } else {
      enemyarrayindex++;
     }
    }

    // 每2秒添加一个敌机子弹
    countenemybullet++;
    if (countenemybullet % 40 == 0) {
     for (int i = 0; i < vcenemy.size(); i++) {
      enemy en = vcenemy.elementat(i);
      // 不同类型敌机不同的子弹运行轨迹
      int bullettype = 0;
      switch (en.type) {
      // 苍蝇
      case enemy.type_fly:
       bullettype = bullet.bullet_fly;
       break;
      // 鸭子
      case enemy.type_duckl:
      case enemy.type_duckr:
       bullettype = bullet.bullet_duck;
       break;
      }
      vcbullet.add(new bullet(bmpenemybullet, en.x + 10,
        en.y + 20, bullettype));
     }
    }
    // 处理敌机子弹逻辑
    for (int i = 0; i < vcbullet.size(); i++) {
     bullet b = vcbullet.elementat(i);
     if (b.isdead) {
      vcbullet.removeelement(b);
     } else {
      b.logic();
     }
    }

    //每1秒添加一个主角子弹
    countplayerbullet++;
    if (countplayerbullet % 20 == 0) {
     vcbulletplayer.add(new bullet(bmpbullet, player.x + 15, player.y - 20, bullet.bullet_player));
    }

    // 处理敌机与主角的碰撞
    for (int i = 0; i < vcenemy.size(); i++) {
     if (player.iscollsionwith(vcenemy.elementat(i))) {
      // 发生碰撞,主角血量-1
      player.setplayerhp(player.getplayerhp() - 1);
      // 当主角血量小于0,判定游戏失败
      if (player.getplayerhp() <= -1) {
       gamestate = game_lost;
      }
     }
    }

    //处理主角子弹逻辑
    for (int i = 0; i < vcbulletplayer.size(); i++) {
     bullet b = vcbulletplayer.elementat(i);
     if (b.isdead) {
      vcbulletplayer.removeelement(b);
     } else {
      b.logic();
     }
    }

    //处理敌机子弹与主角碰撞
    for (int i = 0; i < vcbullet.size(); i++) {
     if (player.iscollsionwith(vcbullet.elementat(i))) {
      //发生碰撞,主角血量-1
      player.setplayerhp(player.getplayerhp() - 1);
      //当主角血量小于0,判定游戏失败
      if (player.getplayerhp() <= -1) {
       gamestate = game_lost;
      }
     }
    }

    //处理主角子弹与敌机碰撞
    for (int i = 0; i < vcbulletplayer.size(); i++) {
     //取出主角子弹容器的每个元素
     bullet blplayer = vcbulletplayer.elementat(i);
     for (int j = 0; j < vcenemy.size(); j++) {
      //添加爆炸效果
      //取出敌机容器的每个元与主角子弹遍历判断
      if (vcenemy.elementat(j).iscollsionwith(blplayer)) {
       vcboom.add(new boom(bmpboom, vcenemy.elementat(j).x, vcenemy.elementat(j).y, 7));
      }
     }
    }
   }
   break;

  case game_win:

   break;
  case game_lost:

   break;
  case game_pause:
   break;
  }

 }

 @override
 public void run() {
  while (flag) {
   long start = system.currenttimemillis();
   mydraw();
   logic();
   long end = system.currenttimemillis();
   try {
    if (end - start < 50) {
     thread.sleep(50 - (end - start));
    }
   } catch (interruptedexception e) {
    e.printstacktrace();
   }
  }
 }

 /**
  * surfaceview视图状态发生改变,响应此函数
  */
 @override
 public void surfacechanged(surfaceholder holder, int format, int width,
   int height) {
 }

 /**
  * surfaceview视图消亡时,响应此函数
  */
 @override
 public void surfacedestroyed(surfaceholder holder) {
  flag = false;
 }
}

Android实战打飞机游戏之子弹生成与碰撞以及爆炸效果(5)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。