Android飞机大战游戏详解

整体实现思路:

1.创建BackGround绘制循环滚动图片

2.创建Myplane绘制飞机

3.创建Bullet绘制子弹

4.在Myplane中构造isCollision绘制飞机与boss飞机的碰撞,飞机与子弹的碰撞

5.创建boom绘制爆炸效果

6.创建GameSoundpool添加飞机发射子弹的音效和爆炸音效

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

创建一个Background类,并实现构造方法,用draw方法和logic方法使两张图片紧密连接在一起,当第一张图片小于MySurfaceView高度时另一张图片接着循环
package com.example.a29148.myapplication;

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){

        logic();
        Paint paint = new Paint();
        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();
        }
    }
}

如何绘制飞机:

创建Myplane,实现它的构造方法,draw方法并在MySurfaceView传递参数,在后面还定义了飞机的血量,还定义了一个布尔型的noCollision使手指可以拖动飞机,并判断飞机是否被boss飞机发射的子弹击中和被boss飞机的疯狂模式撞到减少血量;当飞机的血量小于等于零时,判定游戏失败

package com.example.a29148.myapplication;

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){

        logic();
        Paint paint = new Paint();
        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();
        }
    }
}

                    case 2:
                        RectF rectF = new RectF(0,0,getWidth(),getHeight());
                        canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.gamelost),null,rectF,paint);
                        break;

如何绘制子弹:

创建一个Bulle类,并完成它的构造方法,定义speed方法给子弹飞行速度赋值,用switch语句把子弹分为玩家子弹和boss子弹,并定义一个布尔型方法isOut,移除飞出屏幕的子弹
package com.example.a29148.myapplication;

        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=20;
    private boolean isOut;
    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);
        lg();
    }
    private void lg(){

        switch (type){
            //玩家子弹
            case 0:
                y-=speed;
                if(y<0){
                    isOut = true;
                }
                break;
            case 1:
                //Boss子弹
                y+=speed;
                if (y<0){
                    isOut = true;
                }

                break;
            default:
                break;

        }



    }

    public boolean isOut() {
        return isOut;
    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public void setOut(boolean out) {
        isOut = out;
    }
}

如何判断碰撞:

在Myplane类和bossplane定义一个isCollision方法并定义布尔型noCollision变量,判断子弹的位置是否落在飞机所在的xy轴位置,如果是就移除子弹并减少血量
public boolean isCollision(BossPlane bossPlane) {
        if (noCollision) {
            return false;
        } else {

            if (bossPlane.getY() + bossPlane.getH() > y && bossPlane.getY() + bossPlane.getH() < y + height) {
                if (x < bossPlane.getX() && x + width > bossPlane.getX()) {
                    noCollision = true;
                    if (hp >= 0) {
                        hp--;
                    }
                    return true;
                }
                if (x>bossPlane.getX()&&x+width 0) {
                        hp--;
                    }
                    return true;
                }
                if(xbossPlane.getX()+bossPlane.getW()){
                    noCollision = true;
                    if (hp > 0) {
                        hp--;
                    }
                    return true;
                }


            }
            return false;
        }
    }

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

如何绘制爆炸效果:

创建一个Boom类,实现它的构造方法,定义两个int型变量crrentFrame和totalFrame,和一个布尔型变量isOut并想MySurfaceView里面传递参数用canvas.clipRect剪切图片,在用canvas.clipRect时要用canvas.save和canvas.restore当currentFrame小于totalFrame时产生爆炸效果
package com.example.a29148.myapplication;

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

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

    public Boom(Bitmap bitmap, int x, int y, int totalFrame) {
        this.bitmap = bitmap;
        this.x = x;
        this.y = y;
        this.totalFrame = totalFrame;
        frameH = bitmap.getHeight();
        frameW = bitmap.getWidth()/totalFrame;
    }
    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();
        lg();
    }
    public void lg(){
        if(currentFrame

如何添加音效:

创建一个GameSoundpool类,实现构造方法,创建一个palySound方法在里面使用switch语句实现音效的快慢并传参到MySurfaceView类中
package com;

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

import com.example.a29148.myapplication.R;

public class GameSoundpool {
    private SoundPool soundPool;
    private int s1;
    private int s2;
    public GameSoundpool(Context context) {
        this.soundPool = new SoundPool(2, AudioManager.STREAM_MUSIC,0);
        s1 = soundPool.load(context, R.raw.shoot,1);
        s2 = soundPool.load(context, R.raw.explosion2,1);
    }
    public void playSound(int s){
        switch (s){
            case 1:
                soundPool.play(s1,1,1,0,1,1.0f);
                break;
            case 2:
                soundPool.play(s2,1,1,0,1,1.0f);
                break;
        }


    }
}
 if(count%20==0){
                            gameSoundpool.playSound(1);
                            Bullet bullet = new Bullet(BitmapFactory.decodeResource(getResources(),R.mipmap.t),plane.getX(),plane.getY(),0);
                            bulletVector.add(bullet);

                        }
if(bossPlane.isCollison(bulletVector.elementAt(i))){
                                gameSoundpool.playSound(2);
                                Boom boom = new Boom(BitmapFactory.decodeResource(getResources(),R.mipmap.boom),bossPlane.getX()+bossPlane.getX()/2,bossPlane.getY(),7);
                                boomVector.add(boom);
                            }

用到的方法:


封装:

飞机的x和y坐标,boss的坐标MySurfaceView中的canvas等都是用到了封装

继承:

MySurfaceView继承了SurfaceView

方法重载:

Myplane中的碰撞类中存在两碰撞就是方法的重载,一个是飞机和子弹的碰撞,一个是飞机和boss飞机的碰撞
 
  


 public boolean isCollision(Bullet bullet) {
        if (noCollision) {
            return false;


        } else {
            if (bullet.getX() > x && bullet.getX() < x + width && bullet.getY() > y && bullet.getY() < y + height) {
                Log.e("AAA", "isCollision: .................................");
                noCollision = true;
                if (hp > 0) {
                    hp--;
                }
                return true;
            }
        }
        return false;
    }

    public boolean isCollision(BossPlane bossPlane) {
        if (noCollision) {
            return false;
        } else {

            if (bossPlane.getY() + bossPlane.getH() > y && bossPlane.getY() + bossPlane.getH() < y + height) {
                if (x < bossPlane.getX() && x + width > bossPlane.getX()) {
                    noCollision = true;
                    if (hp >= 0) {
                        hp--;
                    }
                    return true;
                }
                if (x>bossPlane.getX()&&x+width 0) {
                        hp--;
                    }
                    return true;
                }
                if(xbossPlane.getX()+bossPlane.getW()){
                    noCollision = true;
                    if (hp > 0) {
                        hp--;
                    }
                    return true;
                }


            }
            return false;
        }
    }

接口:

MySurfaceView中的SurfaceHolder.Callback和Rnnable都是接口

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    private SurfaceHolder surfaceHolder;
    private Canvas canvas;//绘制图形的画布
    private boolean isDrawing = true;
    public static int Height;
    public static int Wide;
    private MyPlane plane;
    private Vector bulletVector = new Vector<>();//Vector是线程安全的,ArrayList是非线程安全的
    private Vector boosBulletVector = new Vector<>();
    private VectorboomVector = new Vector<>();
    private int count;
    private GameSoundpool gameSoundpool;
    public static int Game_STATE=3;

收获与感悟:

没上实训课之前辉哥,曾经说过我们上实训课会收获很大,当时我不信,因为去年的c语言的并不好,导致今年的java就有点跟不上节奏,今年java课的老师可能以为我们班的c语言的学的很好,所以课就讲的很快,我许多概念没弄明白就讲完了,上课讲的东西下课就忘了。
但是上了实训课老师又从头开始讲起,许多我没弄懂的概念和代码老师讲的很仔细,很容易明白,而且老师上课也不是只讲理论性的东西,大多数时间都留给我们自己打代码,让我们练习,这都是我们以前课堂上没有的东西,虽然只有短短的一个月时间,但是我感觉比前两个月学到的东西都多,比以前的不理解,只死记硬背的好太多了,这一个月让我重拾了信心,而且最后的一个飞机大战的项目我很感兴趣,因为我学习软件有很大一部分原因是我想自己编写一个游戏,这次的实训课让我感受到了不少压力,原来编写一个游戏需要这么多精力,但是丝毫没降低我的兴趣,我会一直向着我的目标前进的

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