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

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

更多相关文章

  1. GitHub 标星 2.5K+!教你通过玩游戏的方式学习 VIM!
  2. Android游戏引擎《Rokon》学习笔记六:一个使用Box2D的Rokon小例子
  3. android chess---GobangView.java
  4. 木瓜(Papaya) Android开发者创业大赛即将启动
  5. 201204NEWS
  6. Android游戏开发设计步骤总结
  7. Android(安卓)小米盒子游戏手柄按键捕获 - 能获取到的 home 键依
  8. [Unity3D]Unity3D游戏开发之Unity与Android交互调用研究
  9. 【Android游戏开发十六】Android(安卓)Gesture之【触摸屏手势识

随机推荐

  1. 花样Android ProgressBar 史上最强大讲解
  2. Android常用的15个框架
  3. Android(安卓)camera 默认显示黑白的问题
  4. 软键盘默认不弹出,点击别的控件让EditText
  5. Android基本控件和事件以及消息总结
  6. android切换到后台图片纹理丢失的解决方
  7. Android : 登录并保存密码
  8. Android SQLite数据库升级的问题
  9. Android下USB Accessory的实现分析 (四)---
  10. Android 修改app图标和名称的方法