当前位置: 移动技术网 > IT编程>移动开发>Android > Android实战打飞机游戏之怪物(敌机)类的实现(4)

Android实战打飞机游戏之怪物(敌机)类的实现(4)

2019年07月24日  | 移动技术网IT编程  | 我要评论

陈玺羽,一年级下册音乐教学计划,邯郸美的城

先看看效果图:

分析: 根据敌机类型区分 敌机 运动逻辑 以及绘制

/**
 * 敌机
 * 
 * @author liuml
 * @time 2016-5-31 下午4:14:59
 */
public class enemy {

  // 敌机的种类标识
  public int type;
  // 苍蝇
  public static final int type_fly = 1;
  // 鸭子(从左往右运动)
  public static final int type_duckl = 2;
  // 鸭子(从右往左运动)
  public static final int type_duckr = 3;
  // 敌机图片资源
  public bitmap bmpenemy;
  // 敌机坐标
  public int x, y;
  // 敌机每帧的宽高
  public int framew, frameh;
  // 敌机当前帧下标
  private int frameindex;
  // 敌机的移动速度
  private int speed;;
  // 判断敌机是否已经出屏
  public boolean isdead;

  // 敌机的构造函数
  public enemy(bitmap bmpenemy, int enemytype, int x, int y) {
    this.bmpenemy = bmpenemy;
    framew = bmpenemy.getwidth() / 10;
    frameh = bmpenemy.getheight();
    this.type = enemytype;
    this.x = x;
    this.y = y;
    // 不同种类的敌机血量不同
    switch (type) {
    // 苍蝇
    case type_fly:
      speed = 25;
      break;
    // 鸭子
    case type_duckl:
      speed = 3;
      break;
    case type_duckr:
      speed = 3;
      break;
    }
  }

  // 敌机绘图函数
  public void draw(canvas canvas, paint paint) {
    canvas.save();
    canvas.cliprect(x, y, x + framew, y + frameh);
    canvas.drawbitmap(bmpenemy, x - frameindex * framew, y, paint);
    canvas.restore();
  }

  // 敌机逻辑ai
  public void logic() {
    // 不断循环播放帧形成动画
    frameindex++;
    if (frameindex >= 10) {
      frameindex = 0;
    }
    // 不同种类的敌机拥有不同的ai逻辑
    switch (type) {
    case type_fly:
      if (isdead == false) {
        // 减速出现,加速返回
        speed -= 1;
        y += speed;
        if (y <= -200) {
          isdead = true;
        }
      }
      break;
    case type_duckl:
      if (isdead == false) {
        // 斜右下角运动
        x += speed / 2;
        y += speed;
        if (x > mysurfaceview.screenw) {
          isdead = true;
        }
      }
      break;
    case type_duckr:
      if (isdead == false) {
        // 斜左下角运动
        x -= speed / 2;
        y += speed;
        if (x < -50) {
          isdead = true;
        }
      }
      break;
    }
  }

}

在mysurfaceview 中 生成敌机

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;

  /**
   * 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);

    // 实例敌机容器
    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);
            }

          } else {
            // boss 绘制
          }
          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++;
          }
        }
      }
      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类

package com.gsf;

import android.graphics.bitmap;
import android.graphics.canvas;
import android.graphics.paint;
import android.view.keyevent;

public class player {

  private int playerhp = 3;

  private bitmap bmpplayerhp;
  // 主角坐标以及位图
  private int x, y;
  private bitmap bmpplayer;
  // 主角移动速度

  private int speed = 5;
  // 主角移动标识
  private boolean isup, isdown, isleft, isright;

  // 主角的构造函数
  public player(bitmap bmpplayer, bitmap bmpplayerhp) {
    this.bmpplayer = bmpplayer;
    this.bmpplayerhp = bmpplayerhp;
    // 飞机初始位置
    x = mysurfaceview.screenw / 2 - bmpplayer.getwidth() / 2;
    y = mysurfaceview.screenh - bmpplayer.getheight();
  }

  // 主角游戏绘制方法
  public void draw(canvas canvas, paint paint) {

    // 绘制主角
    canvas.drawbitmap(bmpplayer, x, y, paint);
    // 绘制血量

    for (int i = 0; i < playerhp; i++) {
      canvas.drawbitmap(bmpplayerhp, i * bmpplayerhp.getwidth(),
          mysurfaceview.screenh - bmpplayerhp.getheight(), paint);
    }

  }

  /**
   * 按键事件监听
   */
  public void onkeydown(int keycode, keyevent event) {
    if (keycode == keyevent.keycode_dpad_up) {
      isup = true;
    }
    if (keycode == keyevent.keycode_dpad_down) {
      isdown = true;
    }
    if (keycode == keyevent.keycode_dpad_left) {
      isleft = true;
    }
    if (keycode == keyevent.keycode_dpad_right) {
      isright = true;
    }
  }

  public void onkeyup(int keycode, keyevent event) {
    if (keycode == keyevent.keycode_dpad_up) {
      isup = false;
    }
    if (keycode == keyevent.keycode_dpad_down) {
      isdown = false;
    }
    if (keycode == keyevent.keycode_dpad_left) {
      isleft = false;
    }
    if (keycode == keyevent.keycode_dpad_right) {
      isright = false;
    }
  }

  /**
   * 游戏逻辑
   */
  public void logic() {
    if (isup) {
      y -= speed;
    }
    if (isdown) {
      y += speed;
    }
    if (isleft) {
      x -= speed;
    }
    if (isright) {
      x += speed;
    }
    // 判断屏幕x边界
    if (x + bmpplayer.getwidth() >= mysurfaceview.screenw) {
      x = mysurfaceview.screenw - bmpplayer.getwidth();
    } else if (x <= 0) {
      x = 0;
    }
    // 判断屏幕y边界
    if (y + bmpplayer.getheight() >= mysurfaceview.screenh) {
      y = mysurfaceview.screenh - bmpplayer.getheight();
    } else if (y <= 0) {
      y = 0;
    }

  }


  //设置主角血量
  public void setplayerhp(int hp) {
    this.playerhp = hp;
  }

  //获取主角血量
  public int getplayerhp() {
    return playerhp;
  }


  //判断碰撞(敌机与主角子弹碰撞)
  public boolean iscollsionwith(enemy bullet) {
      int x2 = bullet.x;
      int y2 = bullet.y;
      int w2 = bullet.framew;
      int h2 = bullet.frameh;
      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;
      }
      //发生碰撞,让其死亡
      //isdead = true;
      return true;
    }


}

在mysurface中 加上碰撞逻辑

  /**
   * 游戏逻辑
   */
  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++;
          }
        }
        //处理敌机与主角的碰撞
        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;
            }
          }
        }
      }
      break;

// 计时器
  private int nocollisioncount = 0;
  // 因为无敌时间
  private int nocollisiontime = 60;
  // 是否碰撞的标识位
  private boolean iscollision;

//判断碰撞(主角与敌机)
  public boolean iscollsionwith(enemy en) {
    //是否处于无敌时间
    if (iscollision == false) {
      int x2 = en.x;
      int y2 = en.y;
      int w2 = en.framew;
      int h2 = en.frameh;
      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;
    }
  }

修改逻辑方法

  /**
   * 游戏逻辑
   */
  public void logic() {
    if (isup) {
      y -= speed;
    }
    if (isdown) {
      y += speed;
    }
    if (isleft) {
      x -= speed;
    }
    if (isright) {
      x += speed;
    }
    // 判断屏幕x边界
    if (x + bmpplayer.getwidth() >= mysurfaceview.screenw) {
      x = mysurfaceview.screenw - bmpplayer.getwidth();
    } else if (x <= 0) {
      x = 0;
    }
    // 判断屏幕y边界
    if (y + bmpplayer.getheight() >= mysurfaceview.screenh) {
      y = mysurfaceview.screenh - bmpplayer.getheight();
    } else if (y <= 0) {
      y = 0;
    }

    // 处理无敌状态
    if (iscollision) {
      // 计时器开始计时
      nocollisioncount++;
      if (nocollisioncount >= nocollisiontime) {
        // 无敌时间过后,接触无敌状态及初始化计数器
        iscollision = false;
        nocollisioncount = 0;
      }
    }

  }

修改主角的绘制
player 类

// 主角游戏绘制方法
  public void draw(canvas canvas, paint paint) {

    // 绘制主角
    // 当处于无敌时间时,让主角闪烁
    if (iscollision) {
      // 每2次游戏循环,绘制一次主角
      if (nocollisioncount % 2 == 0) {
        canvas.drawbitmap(bmpplayer, x, y, paint);
      }
    } else {
      canvas.drawbitmap(bmpplayer, x, y, paint);
    }
    // 绘制血量

    for (int i = 0; i < playerhp; i++) {
      canvas.drawbitmap(bmpplayerhp, i * bmpplayerhp.getwidth(),
          mysurfaceview.screenh - bmpplayerhp.getheight(), paint);
    }

  }

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网