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

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

程序员文章站 2024-03-05 09:08:00
先看看效果图: 分析: 根据敌机类型区分 敌机 运动逻辑 以及绘制 /** * 敌机 * * @author liuml * @tim...

先看看效果图:

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

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

/**
 * 敌机
 * 
 * @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;

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

// 计时器
  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;
      }
    }

  }

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

修改主角的绘制
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);
    }

  }

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