Andro stutio 飞机大战详解

本文详细介绍了使用Java开发一款简单的飞机大战游戏的过程,包括背景图片循环滚动、飞机及子弹绘制、碰撞检测、爆炸效果实现等内容,并探讨了面向对象设计原则的应用。

整体实现思路

1.运行代码,出现背景滚动,飞机往上飞,发出子弹,敌机向下发射子弹。
2.飞机击中敌机发生爆炸,消耗敌机血量,血量为零时胜利。
3.敌机击中我方飞机发生爆炸,消耗我方飞机血量,血量为零是失败。

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

在MySurfaceView中创建run方法

public void run() {
        Paint paint = new Paint();
        BackGround backGround = new BackGround(BitmapFactory.decodeResource(getResources(), (Integer) R.mipmap.img_bg_level_2));

调用mipmap中的背景图片
再创建BackGround类



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+=10;
        y2+=10;
        if (y1>=MySurfaceView.height){
            y1=y2-bitmap.getHeight();//移动到第二张图片的顶部
        }
        if (y2>=MySurfaceView.height){
            y2=y1-bitmap.getHeight();
        }
    }
}

效果如下
这里写图片描述

如何绘制飞机

run方法中

 plane = new Myplane(BitmapFactory.decodeResource(getResources(), R.mipmap.myplan),BitmapFactory.decodeResource(getResources(), R.mipmap.myhp));

这里写图片描述
再创建一个飞机类 MyPlane 添加击中闪烁 、无敌时间效果。

  public Myplane(Bitmap bitmap, Bitmap bitmapHp){
        this.bitmap = bitmap;
        this.bitmapHp = bitmapHp;
        x = MySurfaceView.width/2-bitmap.getWidth()/2;
        y = MySurfaceView.height-bitmap.getHeight();
        width = bitmap.getWidth();
        height = bitmap.getHeight();
    }
    public void draw(Canvas canvas,Paint paint){
        if(hp<=0){
            MySurfaceView.GAME_STATE = 2;
        }
        if (noCollision){
            noCollisionCount++;
            if (noCollisionCount%10==0){
                canvas.drawBitmap(bitmap,x,y,paint);//飞机闪烁
            }
            if (noCollisionCount>100){//无敌时间
                noCollision = false;
                noCollisionCount = 0;
            }
        }else {
            //非无敌状态
            canvas.drawBitmap(bitmap,x,y,paint);
        }

        for (int i = 0; i<hp; i++){
            canvas.drawBitmap(bitmapHp,i*bitmapHp.getWidth(),MySurfaceView.height-bitmapHp.getHeight(),paint);
        }

    }

如何绘制子弹

创建个子弹类Bullet类
并加入BossBullet创建方法这里写图片描述

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

    }

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

    public void logic() {

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

如何判断碰撞(子弹与飞机碰撞,飞机与飞机碰撞)

子弹与Boss碰撞

public boolean  isCollison(Bullet bullet){  
        if (bullet.getX()>x&&bullet.getX()+bullet.getBitmap().getWidth()<x+frameW&&bullet.getY()>y&&bullet.getY()<y+frameH){  
         bossHp--;  

         bullet.setDead(true);//设置子弹状态,碰撞后修改子弹状态为dead,从数组中移除  
            if(bossHp < 0 ){  
                MySurfaceView.GAME_STATE =1;  
            }  

         return  true;  
        }  
       return  false; 

飞机与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这里写图片描述

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<totalFrame){  
         currentFrame++;  
     }else{  
          isEnd = true;  
     }  
 }  

    public boolean isEnd() {  
        return isEnd;  
    }  

如何添加音效

GameSoundPool 类中 加入如下代码
开火音效
战斗背景音效

 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);
        s3 = soundPool.load(context,R.raw.bgm_zhandou2,1);
    }

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

封装

每一个类中的属性基本都用到了封装方法如

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

继承

MySurfaceView 类中

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

    public static int GAME_STATE = 0

Boom类中

public class Boom extends Bullet {
    private Bitmap bitmap;
    private int x,y;
    private int totalFrame;

多态

public class Boom extends Bullet {
    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) {
        super();
        this.bitmap = bitmap;
        this.x = x;
        this.y = y;
        this.totalFrame = totalFrame;
        frameW = bitmap.getWidth()/totalFrame;
        frameH =  bitmap.getHeight();

方法重载

方法名相同,形参列表不同
如下

   public void surfaceCreated(SurfaceHolder holder) {
        new Thread(this).start();//启动子线程
        height = getHeight();//把getHeight(获取height的方法)的返回值赋给height
        width = getWidth();

    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

我的收获与感悟

经过四周的实训课,感悟良多。Java编程是一项很严谨的工作:一定要细心,一点点的不严谨,就会出现问题,也可能导致整个项目出错,所谓:千里之堤,毁于蚁穴。
这四周,很辛苦,很累。但是回头想想,却又很开心,收获很多,学到很多。总之,这次实训为我提供了与众不同的学习方法和学习体会,为以后走上社会,踏上工作岗位打下了扎实的基础。有了能力,到时候才会是“车到山前必有路“。
相信再不久的未来,会属于我自己的一片天空。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值