飞机大战游戏详解

整体实现思路

通过Android Studio 这个软件实现对飞机大战游戏的代码编写及效果实现。根据要实现的效果分别建如下类

  1. MySurfaceView2. MyPlane 3. BossPlane 4. Boom 5. Bullet 6. GameSoundPool7. BackGround
    用 canvas.drawBitmap方法实现背景图,飞机,子弹,爆炸效果的视觉效果
    通过Vector数组存入子弹,再循环打印
    通过 onTouchEvent移动飞机
    用GameSoundPool方法实现子弹,爆炸效果等音效

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

通过canvas.drawBitmap来实现

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

如何绘制飞机

通过canvas.drawBitmap绘制,xy坐标默认为屏幕的最下方,之后的xy跟随手指移动 (onTouchEvent)

  public Myplane(Bitmap bitmap, Bitmap bitmapHp) {
        this.bitmapHp = bitmapHp;
        this.bitmap = bitmap;
        x = MySurfaceView.width / 2 - bitmap.getWidth() / 2;//中间
        y = MySurfaceView.height - bitmap.getHeight();
        }
        public void draw(Canvas canvas, Paint paint) {
    canvas.drawBitmap(bitmap, x, y, paint);
         }

如何绘制子弹

和飞机类基本相同
定义一个Vector数组bullet,存储Bullet的对象
在MySurfaceView中定义一个计数器count,每次运行run方法中的while中的内容时,就让这个计数器count++;
再在while中作判断,当count%50=0时,就往数组bullet中添加一个Bullet的对象,再用for循环
bullet.elementAt(i)调用Bullet中的draw方法,设置每次画出子弹后让子弹的y轴–,再判断子弹是否击中目标或者飞出屏幕,
选择是否remove该对象
用switch 语句判断玩家和boss 的子弹

if (count%50==0){//添加子弹
    MyBullet myBullet = new MyBullet(zidan,myPlane.getX()+bitmap1.getWidth()/2-zidan.getWidth()/2,myPlane.getY()-zidan.getHeight(),0);
    myBulletVector.add(myBullet);
}
for (int i = 0;i//画出子弹
    myBulletVector.elementAt(i).draw(canvas,paint);
}
//判断子弹是否击中Boss
if (x>myBullet.getX()+myBullet.getBitmap().getWidth()||x+frameWmyBullet.getY()+myBullet.getBitmap().getHeight()||y+bitmap.getHeight()else {
    return true;
}
return false;
//判断子弹是否飞出屏幕
 public boolean fly(){
        if (y>MySurfaceView.heigth){
            return true;
        }
        return false;
   }
  //删除飞出屏幕的子弹
  for (int i = 0;iif (myBulletVector.elementAt(i).getIsDead()){
          myBulletVector.remove(i);
      }
 }

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

//子弹与飞机碰撞
    public boolean isCollision(Bullet bullet) {
        if (noCollision) {
            return false;
        }
        if (bullet.getX() > x && bullet.getX() < x + width && bullet.getY() > y && bullet.getY() < y + height) {
            noCollision = true;
            if (Hp > 0) {
                Hp--;
            }
            return true;
        }
        return false;

    }
//飞机与飞机碰撞
    public boolean Attack(Bossplane bossplane) {
        if (noCollision) {
            return false;

        }
        if(ybossplane.getY() ){

            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+width > bossplane.getX()+bossplane.getFrameW()) {//我方飞机右边碰撞
                noCollision = true;
                if (Hp > 0) {
                    Hp--;
                }
                return true;
            }
        }

        return false;
    }

如何绘制爆炸效果

需要用到Vector数组
Vector boom = new Vector<>();
只不过在绘制时,爆炸图片需要进行裁剪,再每次往左偏移七分之一的爆炸图片的宽度(我的爆炸图片是七帧的)
每次移动一帧,currentFrame++,currentFrame++到7时,数组就移除该对象;

 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 (currentFrameelse {
            isEnd = true;
        }
    }

如何添加音效

创建一个GameSoundPool类
定义一个SoundPool对象
定义对象S1 ,S2
在构造方法中给s赋初始值,导入音乐文件
用soundPool.play播放
用swicth语句判断,再用SoundPool调用

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,1,1,1.0f);
                break;
            case 2:
                soundPool.play(s2,1,1,1,1,1.0f);
                break;
        }
    }
}

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

封装(高内聚低耦合,不同的访问权限,提高安全性)

用几种访问修饰符实现封装(private,default,package,public)

    private SurfaceHolder surfaceHolder;
    private Canvas canvas;
    private boolean isDrawing = true;
    public static int height;
    public static int width;

继承(extends super 关键字,低耦合,安全性,复用性)

public class MySurfaceView extends SurfaceView  {..}
public class Boom extends Bullet{...}

多态(编译时,字解码; 运行时,Jvm)

方法重载

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

    }

    public Bullet() {

    }

接口

在MysufaceView中实现了两个接口
SurfaceHolder.Callback,与Runnable

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable

Vector数组

    private Vector bulletVector = new Vector <>();
    private VectorbossBulletVector = new Vector <>();
    private VectorboomVector = new Vector <>();

构造方法(为对象赋初始值)

 Paint paint = new Paint();
 Bullet bullet = new Bullet();

收获与感悟

这一个月的java实训,主要就是复习java的基础知识,并且开始尝试做一些小程序:如图书管理系统,自动售货机,打飞机等几款,收获很多。虽然持续一个月都是Java实训,但是在其中,我深深的感受到自己知识的匮乏,通过每天在博客上写小白日志,回顾和复习当天的成果,我认为这种学习方式很不错。
对于这次的打飞机项目,刚刚接触是完全处于种懵逼状态,突然换了一款安卓软件,感觉比Eclipse 较复杂些,虽然给了我们充足的时间去熟悉这款软件,但我还是不是很懂,只有通过不断的练习,渐渐搞清楚了其使用方式,体会到了其的高智能化,打飞机这款游戏软件,其程序编写体现了循序渐进,逐层提高,最终完善的思想,这是一个不断修改,不断提高的过程。
这个项目,我认识到自己依旧有很多不足,也知道了一个程序的编写的重中之重就是把握其思路,只有思路清晰,代码写起来才得心应手,这是建立在有一定水平的基础之上的,因而,目前我要侧重于加强编程水准及经验上,即多练,多想,多看上.

你可能感兴趣的:(Java)