android 飞机大战详解

一. 整体实现思路

  1. 飞机是一个对象,这个对象的属性包括血量、x,y轴,图片
  2. 飞机在飞行中会发射子弹,所以飞机应该对应着一个子弹的线程
  3. 因为子弹飞行过程中,以及飞机飞行过程中都会碰到障碍物(子弹、敌机),所以在碰撞的一瞬间应该会有一个线程释放出碰撞效果
  4. 在监听屏幕触摸事件等方面运用onTouchEvent方法

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

铺两张同样的背景图,依次向下滚动。当第一张出现的背景图的y轴坐标大于等于屏幕底部的y轴坐标时,立刻移动到第二张图片的顶部,同样的,当第二张背景图的y轴坐标大于等于屏幕底部的y轴坐标时,立刻移动到第一张图片的顶部,在视觉效果上形成循环。

 public void logic() {
        y1+=10;
        y2+=10;
        if (y1>=MySurfaceView.height){
            y1=y2-bitmap.getHeight();//移动到第二张图片的顶部
        }
        if (y2>=MySurfaceView.height){
            y2=y1-bitmap.getHeight();
        }
    }

三. 如何绘制飞机

在绘制飞机的时候记得把血量带上

 private Bitmap bitmap;
    private Bitmap bitmapHp;
    private int x,y;
    private int width,height;
    private boolean noCollision;
    private int noCollisionCount;

    private int hp =3;

    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  myPlane (Canvas canvas,Paint paint){  
       if (noCollsion){  
           count++;  
           if (count%8==0){  
               canvas.drawBitmap(bitmap1,x,y,paint);  
           }  
           if (count==100){  
               noCollsion=false;  
               count=0;  
           }  
       }else {  
           canvas.drawBitmap(bitmap1,x,y,paint);  
       }  
       for (int i =0;i<hp;i++){  
           canvas.drawBitmap(bitmaphp,i*bitmaphp.getWidth(),MySurfaceView.heigth-bitmaphp.getHeight(),paint);  
       }  
   }  

四. 如何绘制子弹

子弹的属性有x,y轴,速度以及当子弹飞出屏幕外时移除它
我们把玩家子弹与Boss子弹写在一个类中,用0代表玩家子弹,1代表Boss子弹
①绘制玩家的子弹

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

设置玩家子弹飞行速度与方向以及移除玩家子弹,因为在视觉效果中玩家子弹是向上飞的,所以y轴为-

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

②绘制Boss子弹

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

设置Boss子弹飞行速度与方向以及移除,与玩家子弹相反,Boss子弹y轴为+

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

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

我们设定当子弹的坐标与飞机的坐标重合时判定子弹与飞机碰撞;
玩家飞机与Boss飞机坐标重合时判定飞机与飞机碰撞

private void ff(){  
      switch (teyp){  
          case 0:  
              y-=speed;  
              if (y<-300){  
                  isDead=true;  
              }  
              break;  
          case 1:  
              y+=(speed/2);  
              if (y>MySurfaceView.heigth){  
                  isDead=true;  
              }  
              break;  
      }  
  }  

六. 如何绘制爆炸效果

首先继承子弹类,因为子弹碰撞到飞机后才会产生爆炸,然后将爆炸效果一帧帧的绘制出来

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  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,定义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.shoot,1);
        s2 = soundPool.load(context,R.raw.explosion2,1);
        s3 = soundPool.load(context,R.raw.bgm_zhandou2,1);
    }
    public void playSound(int s) {
        switch (s){
            case 1:
                soundPool.play(s1,1,1,1,1,1.0f);
                break;
            case 2:
                soundPool.play(s2,1,1,1,1,1.0f);
                break;
            case 3:
                soundPool.play(s3,1,1,1,1,1.0f);
                break;

        }
    }
    }

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

①封装到处都有吧
②爆炸效果那里就用到了继承
③玩家子弹与Boss子弹用到了多态

⑤SurfaceHolder.Callback,与Runnable

九. 收获与感悟

一个极其简单的小飞机游戏却花掉了我一周的时间(也可以说是一个月,之前三周学的基础知识就在这里得到了应用),真的无法想象我们平时玩的例如LOL、dnf、吃鸡之类的游戏是由多少行代码构成的。在编程这一行我算是没什么天赋的平庸之辈,只能用努力去不断弥补。
路漫漫其修远兮,吾将上下而求索。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值