JAVA小白的第二个项目—飞机大战分步骤理解流程

项目简单简介

飞机大战是集成这一个月实训以来的成果,其中包括了所学的封装,继承,多态,方法的重载等多个知识点构成的一款简单的小游戏。经过一个礼拜的时间将此项目完成,由多个模块组成。

这个代码我们一共需要创建7个类

一.如何实现游戏背景图滚动播放

这个游戏首先的第一个问题就是呈现出飞机正在向前飞行的效果,也就是如何将图片一张接着一张无缝的滚动播放
在MySurfacView的画布上将背景图片上传
我们先创建Blackground类,并创建logic方法

package com.example.administrator.myapplication9;

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

如何绘制飞机

我们需要创建一只画笔,锁定画布
并在MySurfaceView中创建run方法

  public void run() {
        gameSoundPool.playSound(3);

        Paint paint = new Paint();
        BackGround backGround = new BackGround(BitmapFactory.decodeResource(getResources(), R.mipmap.img_bg_level_3));
        plane = new Myplane(BitmapFactory.decodeResource(getResources(), R.mipmap.myplane),BitmapFactory.decodeResource(getResources(), R.mipmap.myhp));
        BossPlane bossPlane = new BossPlane(BitmapFactory.decodeResource(getResources(), R.mipmap.bossplane));

这样就将敌机和我方机器绘制在了画布上

如何绘制子弹

绘制子弹和绘制飞机的方法类似,创建一个子弹(bullet)类,在MySurfaceView中需要实例化子弹对象,然后将子弹的图片上传,我们还需要创建我方子弹,敌方子弹的数组eg: private VectorbulletVector = new Vector <>();像这样的一个数组用来存放子弹,调用bullet类,在bullet类中创造logic方法,用if语句进行判断,分别进行判断,并给玩家子弹和敌方子弹进行设置

这是先创建一个bullet类,子弹类,并在里面创建方法,设置子弹的运行
这里写package com.example.administrator.myapplication9;
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;
        }
    }

    public boolean isDead() {
        return isDead;
    }
    public Bitmap getBitmap(){
        return bitmap;
    }
    public int getX(){
        return x;
    }

    public int getY() {
        return y;
    }

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

代码片
这是在MySurfacView中如何调用bullet类,并且进行实例化,用循环语句实现运行

这一段代码是在开始创建子弹的数组

 private VectorbulletVector = new Vector <>();
    private VectorbossBulletVector = new Vector <>();
    private VectorboomVector = new Vector <>();
 public void run() {
        gameSoundPool.playSound(3);

        Paint paint = new Paint();
        BackGround backGround = new BackGround(BitmapFactory.decodeResource(getResources(), R.mipmap.img_bg_level_3));
        plane = new Myplane(BitmapFactory.decodeResource(getResources(), R.mipmap.myplane),BitmapFactory.decodeResource(getResources(), R.mipmap.myhp));
        BossPlane bossPlane = new BossPlane(BitmapFactory.decodeResource(getResources(), R.mipmap.bossplane));

        while (isDrawing) {
            count++;

            try {
                canvas = surfaceHolder.lockCanvas();//锁定(选定)画布
                canvas.drawColor(Color.WHITE);
             switch (GAME_STATE){

                 case 0:
                     backGround.draw(canvas, paint);
                     plane.draw(canvas, paint);
                     bossPlane.draw(canvas,paint);


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


                     for (int i = 0;i

                         if (bulletVector.elementAt(i).isDead()) {
                             bulletVector.remove(i);

                         }
                     }
                     for (int i = 0;i

                         bulletVector.elementAt(i).draw(canvas,paint);
                         if (bossPlane.isCollision(bulletVector.elementAt(i))){
                             gameSoundPool.playSound(2);
                             Boom boom = new Boom(BitmapFactory.decodeResource(getResources(),R.mipmap.boom),bossPlane.getX()+bossPlane.getFrameW()/4,bossPlane.getY(),7);
                             boomVector.add(boom);
                         }
                     }

                     for (int i=0;i
                         if (boomVector.elementAt(i).isDead()){
                             boomVector.remove(i);
                         }else{
                             boomVector.elementAt(i).draw(canvas,paint);
                         }
                     }

                     if(count%40==0){
                         Bullet bullet = new Bullet(BitmapFactory.decodeResource(getResources(), R.mipmap.bossbullet),bossPlane.getX()+bossPlane.getFrameW ()/2,bossPlane.getY()+bossPlane.getFrameH(),1);         
                         //Bullet bullet1 = new Bullet(BitmapFactory.decodeResource(getResources(), R.mipmap.bossbullet),bossPlane.getX()+bossPlane.getFrameW(),bossPlane.getY()+bossPlane.getFrameH(),1);
                         bossBulletVector.add(bullet);
                         // bossBulletVector.add(bullet1);
                     }

                     for (int i = 0;i < bossBulletVector.size(); i++) {

                         if (bossBulletVector.elementAt(i).isDead()) {
                             bossBulletVector.remove(i);

                         }
                     }
                     for (int i = 0;i < bossBulletVector.size(); i++){

                         bossBulletVector.elementAt(i).draw(canvas,paint);
                         plane.isCollision(bossBulletVector.elementAt(i));
                     }
                     plane.isCollision(bossPlane);
                        break;
                 case 1:
                     RectF rectF1 = new RectF(0,0,getWidth(),getHeight());
                     canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.gamewin),null,rectF1,paint);
                     break;
                 case 2:
                     RectF rectF = new RectF(0,0,getWidth(),getHeight());
                     canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.gamelost),null,rectF,paint);
                     break;
             }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (canvas != null) {
                    surfaceHolder.unlockCanvasAndPost(canvas);//解锁画布,显示到屏幕上
                }
            }

以上这一段是完整的一段run方法,里面有子弹的绘制,还有如何运行程序,下面这一小段代码就是如何在MySurfaceView里如何绘制子弹

 Bullet bullet = new Bullet(BitmapFactory.decodeResource(getResources(), R.mipmap.bossbullet),bossPlane.getX()+bossPlane.getFrameW()/2,bossPlane.getY()+bossPlane.getFrameH(),1);
                         //Bullet bullet1 = new Bullet(BitmapFactory.decodeResource(getResources(), R.mipmap.bossbullet),bossPlane.getX()+bossPlane.getFrameW(),bossPlane.getY()+bossPlane.getFrameH(),1);
                         bossBulletVector.add(bullet);
                         // bossBulletVector.add(bullet1);

实例化,然后将子弹绘制出来

如何判断碰撞

在飞机大战中碰撞分为两种,飞机与飞机的碰撞,能够子弹与飞机的碰撞,而这一段也是非常重要的,我们需要知道飞机的位置,get到飞机的位置,当我方飞机碰撞到敌方飞机的顶部,或子弹打到时,敌方飞机有爆炸效果(爆炸效果如何实现,下文会写),左右时,我方飞机进行闪烁,同样,当敌方子弹闯入我方飞机的范围内,我方飞机闪烁,并且减少血量
在Myplane中建立两个方法 noCollision(Boss),isCollision(myplane)
并用if语句进行条件判断如果碰到血量就–

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; ipublic void touchEvent(MotionEvent event){
        if (event.getAction()==MotionEvent.ACTION_MOVE){
            float ex = (int) event.getX();
            float ey = (int) event.getY();
            if (ex>x&&exy&&eyint) ex-width/2;
                y = (int) ey-height/2;
                if(y<0){
                    y=0;
                }
                if(y+height>MySurfaceView.height){
                    y=MySurfaceView.height-height;
                }
            }
        }
     `

``` public boolean isCollision(Bullet bullet){
        if (noCollision){
            return false;
        }else{
            if (bullet.getX()>x&&bullet.getX()y&&bullet.getY()true;
                if (hp>0){
                    hp--;
                }

                return true;
            }
        }
        return false;
    }


上面的这两段代码实现的判断碰撞,然后不同的飞机的不同反应






"se-preview-section-delimiter">
####如何绘制爆炸效果 当飞机子弹打到敌方飞机时会有爆炸效果,我们需要新建一个Bomm类
"se-preview-section-delimiter">

package com.example.administrator.myapplication9;

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

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

}

同样我们需要get到位置,爆炸的效果是一帧一帧显示的,并且在MySurfaceView中调用,运用for循环





<div class="se-preview-section-delimiter">div>

for (int i = 0;i

package com.example.administrator.myapplication9;

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.shoot,1);
        s2 = soundPool.load(context,R.raw.explosion2,1);
       // s3 = soundPool.load(context,R.raw.bg_logobg,2);
    }
    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;
        }
    }
    }

用switch,case语句进行判断,然后将在MySurfaceView中,将这些音乐写入合适的位置,比如在boss发射子弹时运行哪一个音乐,音乐代码中的参数分别是左右声道,音乐的播放速率。

你可能感兴趣的:(JAVA小白的第二个项目—飞机大战分步骤理解流程)