飞机大战游戏详解

整体实现思路

      1.打开软件,背景开始循环滚动;

      2.玩家飞机开始不断发射子弹(由下往上),Boss飞机在上方来回移动并发射子弹(由上往下);

      3.当玩家飞机碰到Boss发射的子弹,生命值减掉一颗心,减掉全部心时,GameOver;

      4.当敌人和飞机相撞时,生命值减掉一颗心,减掉全部心时,GameOver;     

      5.玩家飞机发射子弹碰到Bosss飞机时,Boss生命值减1,减掉全部生命值时,GameWin;


如何绘制循环滚动的背景图片

创建一个背景类(BackGround.class),定义两个相同背景图的值,相同速度实现循环。

backGround.draw(canvas, paint);
BackGround backGround = new BackGround(BitmapFactory.decodeResource(getResources(), mipmap.bk));
package com.example.shang.airfight;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;

public class BackGround {
    private int y1;
    private int y2;
    private Bitmap bitmap;

    public BackGround(Bitmap bitmap) {
        this.bitmap = bitmap;
        y1 = 0;
        y2 = y1 - bitmap.getHeight();
    }

    public void draw(Canvas canvas, Paint paint) {
        logic();
        canvas.drawBitmap(bitmap, 0, y1, paint);
        canvas.drawBitmap(bitmap, 0, y2, paint);
    }

    public void logic() {
        y1 += 5;
        y2 += 5;

        if (y1 >= MySurfaceView.height) {
            y1 = y2 - bitmap.getHeight();
        }
        if (y2 >= MySurfaceView.height) {
            y2 = y1 - bitmap.getHeight();
        }
    }
}


如何绘制飞机

创建玩家飞机与Boss飞机的类,设置初始位置,在Mysurfaceview调用显示

plane = new MyPlane(BitmapFactory.decodeResource(getResources(), mipmap.myplane)); 
BossPlane bossPlane = new BossPlane(BitmapFactory.decodeResource(getResources(), mipmap.bossplane));
plane.draw(canvas, paint);
bossPlane.draw(canvas, paint);
如何绘制子弹
创建一个子弹类(Bullet.class),在Mysurfaceview中调用,

设置玩家飞机子弹位置跟随玩家飞机触摸位置与Boss飞机子弹跟随Boss飞机。

package com.example.shang.airfight;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;

public class Bullet {
    private Bitmap bitmap;
    private int x, y;
    private int speed = 10;
    private boolean isDead;
    private int type;

    public Bullet(Bitmap bitmap, int x, int y, int type) {
        this.bitmap = bitmap;
        this.x = x;
        this.y = y;
        this.type = type;
    }

    public void draw(Canvas canvas, Paint paint) {
        canvas.drawBitmap(bitmap, x, y, paint);
        logic();

    }

    public void logic() {
        switch (type) {
            case 0:
                //玩家子弹
                y -= speed;
                if (y < 0) {
                    isDead = true;
                }
                break;

            case 1:
                //Boss子弹
                y += speed + 2;
                if (y < 0) {
                    isDead = true;
                }
                break;
            default:
                break;
        }
    }
    public boolean isDead() {
        return isDead;
    }
    
    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getType() {
        return type;
        }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public void setDead(boolean dead) { 
        isDead = dead; 
    }
}

//绘制玩家子弹
                       for (int i = 0; i < bulletVector.size(); i++) {

                           bulletVector.elementAt(i).draw(canvas, paint);

                           if (bossPlane.isCollison(bulletVector.elementAt(i))) {
                               gameSoundPool.playSound(3);
                               Boom boom = new Boom(BitmapFactory.decodeResource(getResources(), mipmap.boom), bossPlane.getX()+bossPlane.getFrameW()/3, bossPlane.getY()+bossPlane.getFrameH()/4, 7);

                               boomVector.add(boom);

                           }
                       }
                       for (int i=0 ;i
  //绘制Boss子弹
                       for (int i = 0; i < bossBulletVector.size(); i++) {
                           bossBulletVector.elementAt(i).draw(canvas, paint);
                           plane.isColliseion(bossBulletVector.elementAt(i));
                       }
                       plane.isColliseion(bossPlane);
                       break;


如何判断碰撞

子弹与Boss碰撞

当玩家飞机子弹面积范围接触到BOSS飞机面积范围

    public boolean  isCollison(Bullet bullet){
        if (bullet.getX()>x&&bullet.getX()+bullet.getBitmap().getWidth()y&&bullet.getY()

飞机与BOSS碰撞

当玩家飞机的上方范围接触到BOSS飞机底端范围(设置玩家飞机在Boss飞机左方接触,中间接触,右方接触)

  public boolean isColliseion(Bullet bullet) {
        if (noCollision) {
            return false;
        } else {
            if (bullet.getX() > x && bullet.getX() < x + width && bullet.getY() > y && bullet.getY() < y + height) {
                // Log.e("a", "isColliseion: ......................." );测试
                noCollision = true;
                if (hp > 0) {
                    hp--;
                }
                return true;
            }
        }
        return false;
    }

    public boolean isColliseion(BossPlane bossPlane) {
        if (noCollision) {
            return false;
        } else {
            if (bossPlane.getY() + bossPlane.getFrameH() > y && bossPlane.getY() + bossPlane.getFrameH() < +y + height) {
                if (x < bossPlane.getX() && x + width > bossPlane.getX()) {
                    noCollision = true;
                    if (hp > 0) {
                        hp--;
                    }
                    return true;
                }
                if (x > bossPlane.getX() && x + width < bossPlane.getX() + bossPlane.getFrameW()) {
                    noCollision = true;
                    if (hp > 0) {
                        hp--;
                    }
                    return true;
                }
                if (x > bossPlane.getX() && x < bossPlane.getX() + bossPlane.getFrameW()) {
                    noCollision = true;
                    if (hp > 0) {
                        hp--;
                    }
                    return true;
                }
            }
        }
        return false;
    }


如何绘制爆炸效果

创建一个爆炸类(Boom.class),设置爆炸效果图片的长宽高位置,爆炸效果图片帧数裁剪,

Mysurfaceview,玩家飞机子弹接触Boss飞机范围后实现爆炸跟随效果

  if (bossPlane.isCollison(bulletVector.elementAt(i))) {
                               gameSoundPool.playSound(3);
                               Boom boom = new Boom(BitmapFactory.decodeResource(getResources(), mipmap.boom), bossPlane.getX()+bossPlane.getFrameW()/3, bossPlane.getY()+bossPlane.getFrameH()/4, 7);

                               boomVector.add(boom);

                           }
package com.example.shang.airfight;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;

public class Boom {
    private Bitmap bitmap;
    private int x,y;
    private int totalFrame;
    private int currentFrame;//当前显示的第几幅画面
    private  int frameW,frameH;
    private  boolean isEnd;

 public Boom(Bitmap bitmap , int  x ,int y,int totalFrame){
     this.bitmap = bitmap;
     this.x = x;
     this.y = y;
     this.totalFrame = totalFrame;
     frameW = bitmap.getWidth()/totalFrame;
     frameH = bitmap.getHeight();
 }
 public void  draw(Canvas canvas , Paint paint){
     canvas.save();
     canvas.clipRect(x,y,x+frameW,y+frameH);
     canvas.drawBitmap(bitmap,x-currentFrame*frameW,y,paint);
     canvas.restore();
     logic();
 }
 public  void  logic(){
     if (currentFrame


如何添加音效

res目录下的创建raw目录,放入音频文件,创建一个音乐类(GameSoundPool.class),

用switch语句设置不同音频在Mysurfaceview中调用

package com.example.shang.airfight;

import android.content.Context;
import android.media.AudioManager;

import android.media.SoundPool;

public class GameSoundPool {
    private SoundPool soundPool;
    private int s1;
    private int s2;
    private int s3;

    public GameSoundPool(Context context){
        this.soundPool = new SoundPool(2, AudioManager.STREAM_MUSIC,0);
        s1 = soundPool.load(context,R.raw.bgm_zhandou2,1);
        s2 = soundPool.load(context, R.raw.shoot,1);
        s3 = soundPool.load(context, R.raw.explosion2,1);
    }

    public  void playSound(int s){

        switch (s){
            case 1:
                soundPool.play(s1,1,1,1,0,1.0f);
                break;
            case 2:
                soundPool.play(s2,1,1,1,1,1.0f);
                break;
            case 3:
                soundPool.play(s3,1,1,1,0,1.0f);
                break;
        }
    }
}

gameSoundPool.playSound(1);


哪些地方用到封装、继承、多态、方法重载、接口等

在每个子类中实现不同属性的封装

在玩家飞机类与Boss飞机类位置的方法在Mysurfaceview里实现继承

在玩家飞机生命值与Boss生命值范围使用多态

在玩家飞机与Boss飞机范围碰撞使用了方法重载

在添加音效到Mysurfaceview实现了接口


我的收获与感悟

四周的实训课虽然很累,但我也学到了很多知识,也体会到编程的魅力。

虽然实训课结束了,但我的编程之路才刚刚起步,我要在今后的学习上更加努力,励志做一名优秀的程序员!

2018.05.31

你可能感兴趣的:(飞机大战游戏详解)