飞机大战游戏详解

1.整体实现思路

首先,我们看到飞机大战游戏,它的背景是滚动的,而且是循环滚动的,所以,首先我们要先实现背景的滚动,然后再去添加飞机、boss、子弹等东西。背景滚动做完后,就要添加飞机进去了,而且要使飞机在屏幕的底端并且居中。做完这个后,那么boss的位置就和飞机的类似,在屏幕顶端居中就可以了,但是设置boss的位置有一个难点,因为一张图片上有好几个boss的图片,所以就要用到clipRect的功能。然后就要给飞机和boss添加子弹了,可以把子弹放在飞机的两翼发射,也可以放在头部发射,这要用到简单的数学方法。这些基本的做完之后,为了使游戏有意思,我们加入了飞机碰到boss子弹或者身体时有短暂的无敌状态,这段时间里碰到子弹也不受伤害,boss每隔一段时间会出现“疯狂模式”,就是boss的身体猛地向下移动。接着我们给游戏加入了爆炸效果和音效,玩起来才没有那么单调。然后设置了游戏结束的画面,“you win”和“you lost”。最后给游戏加入开始游戏和退出游戏的菜单界面,这样一个简单的飞机大战游戏便实现了。

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

package com.example.lenovo.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,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();
        }
    }
}

3.如何绘制飞机?

package com.example.lenovo.myapplication;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

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

    private SurfaceHolder surfaceHolder;
    private Canvas canvas;//绘制图形的画布
    private  boolean isDrawing = true;//标志位
    public static int height;
    public MySurfaceView(Context context) {
        super(context);
        init();
    }
    /*
    初始化操作
     */
    private void init(){
        surfaceHolder = getHolder();
        surfaceHolder.addCallback(this);//添加回调事件监听
        setFocusable(true);
        setKeepScreenOn(true);

    }

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

    }

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

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isDrawing = false;

    }

    @Override
    public void run() {

        BackGround backGround = new BackGround(BitmapFactory.decodeResource(getResources(),R.mipmap.bk));
        while (isDrawing) {
            canvas = surfaceHolder.lockCanvas();//锁定(选定)画布
            canvas.drawColor(Color.WHITE);
            backGround.draw(canvas);

            surfaceHolder.unlockCanvasAndPost(canvas);//解锁画布,显示到屏幕上

    }
    }
}

4.如何绘制子弹?

package com.example.lenovo.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 = 10;
    private boolean isDead;

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


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

    private void logic() {
        y-=speed;
        if(y<0){
            isDead = true;
        }
    }

    public boolean isDead() {
        return isDead;
    }

}

5.如何判断碰撞?

import android.graphics.Bitmap;  
import android.graphics.Canvas;  
import android.graphics.Paint;  
import android.view.MotionEvent;  
public class Myplane {  
    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 draw(Canvas canvas,Paint paint){  
        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);  
        }  
  
    }  
    public void touchEvent(MotionEvent event){  
        if (event.getAction()==MotionEvent.ACTION_MOVE){  
            float ex = (int) event.getX();  
            float ey = (int) event.getY();  
            if (ex>x&&ex<x+width&&ey>y&&ey<y+height){  
                x = (int) 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()<x+width&&bullet.getY()>y&&bullet.getY()<y+height){  
                noCollision = true;  
                if (hp>0){  
                    hp--;  
                }  
                return true;  
            }  
        }  
        return false;  
    }  
  
    public int getX() {  
        return x;  
    }  
  
    public int getY() {  
        return y;  
    }  
  
    public int getWidth() {  
        return width;  
    }  
}  
import android.graphics.Bitmap;  
import android.graphics.Canvas;  
import android.graphics.Paint;  
  
public class BossPlane {  
    private Bitmap bitmap;  
    private int x,y;  
    private int frameW,frameH;  
    private int speed=5;  
    private int crazySpeed=50;  
    private int count;//计数器  
    private int time=300;//疯狂模式间隔  
    private boolean isCrazy;  
  
    public BossPlane(Bitmap bitmap) {  
        this.bitmap = bitmap;  
        this.frameW = bitmap.getWidth()/10;  
        this.frameH = bitmap.getHeight();  
        x=MySurfaceView.width/2-frameH/2;  
    }  
    public void draw(Canvas canvas, Paint paint){  
        canvas.save();  
        canvas.clipRect(x,y,x+frameW,y+frameH);  
        canvas.drawBitmap(bitmap,x,y,paint);  
        canvas.restore();  
        logic();  
    }  
    public void logic(){  
        count++;  
        if (isCrazy){  
            y = y+crazySpeed;  
            crazySpeed--;  
            if (y==0){  
                isCrazy = false;  
                crazySpeed = 50;  
            }  
        }else {  
            if (count%time==0){  
                isCrazy=true;  
            }  
            x = x+speed;  
            if (x>MySurfaceView.width-frameH){  
                speed = -speed;  
            }  
            if (x<0){  
                speed = -speed;  
            }  
        }  
    }  
  
    public int getX() {  
        return x;  
    }  
  
    public int getY() {  
        return y;  
    }  
  
    public int getFrameW() {  
        return frameW;  
    }  
  
    public int getFrameH() {  
        return frameH;  
    }  
}  
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 void draw(Canvas canvas, Paint paint) {  
        canvas.drawBitmap(bitmap, x, y, paint);  
        logic();  
    }  
  
    public void logic() {  
  
        switch (type){  
            //玩家子弹  
            case 0:  
                y -= speed;  
                if (y < 0) {  
                    isDead = true;  
                }  
                break;  
            //Boss子弹  
            case 1:  
                y += speed+5;  
                if (y < 0) {  
                    isDead = true;  
                }  
                break;  
            default:  
  
                break;  
        }  
    }  
  
    public boolean isDead() {  
        return isDead;  
    }  
  
  
    public int getX(){  
        return x;  
    }  
  
    public int getY() {  
        return y;  
    }  
}  

6.如何绘制爆炸效果?

package com.example.luwei.smile;

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

    public boolean isEnd() {
        return isEnd;
    }
}

7.如何添加音效?

package com.example.luwei.smile;

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.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;

        }
    }
    }

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

封装:

public static int GAME_STATE = 0;

    private SurfaceHolder surfaceHolder;
    private Canvas canvas;//绘制图形的画布
    private boolean isDrawing = true;//标志位
    public static int height;
    public static int width;
    private Myplane plane;
    private Vector<Bullet>bulletVector = new Vector <>();
    private Vector<Bullet>bossBulletVector = new Vector <>();
    private Vector<Bullet>boomVector = new Vector <>();
    private int count;

 private GameSoundPool gameSoundPool;

继承:

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

}

多态:

public boolean isCollision(Bullet bullet){
            if(bullet.getX()>x&&bullet.getX()+bullet.getBitmap().getWidth()<x+frameW&&bullet.getY()>y&&bullet.getY()<y+frameH){
                bossHp--;
                bullet.setDead(true);
                if (bossHp<0){
                    MySurfaceView.GAME_STATE = 1;
                }
                return true;
            }
            return false;


    }


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){
                noCollision = true;
                if (hp>0){
                    hp--;
                }


                return true;
            }
        }
        return false;

    }

方法重载:

public boolean isCollision(Bullet bullet){}

public boolean isCollision(BossPlane bossPlane) {}

9.我的收获与感悟

      通过这4个星期的学习,学习和生活上都有了很多收获。在生活中我们要自信,不能随随便便否定自己,每个人都有无限的可能性。要多看,多思考,光看还不够,思考才是最重要的。要多看书,书籍是人类进步的阶梯,书中的知识能对我们的人生产生很大的影响。还要养成独立思考的习惯。学习上,从一开始的基本概念都不懂,到现在的基础知识基本能够掌握了,只要肯下功夫,每天复习所学知识点,那么时间长了自然就记住了,而且不容易忘。在写代码方面还差的很远,一定要继续努力!向班里优秀的同学学习、请教,不断地增长知识。

      做任何一件事,都贵在坚持,“靡不有初,鲜克有终”,在每一件事情开始的时候我们都信心十足,活力满满,所以很多事情的开端和前景都是美好的。但是,每一件事情都不可能是一帆风顺的,有时我们的热情与初心便被困难磨没了,失去了热情与激情,也就没有美好的结果。做人善始善终,才能把握机遇。人都说,机遇都是留给有准备的人,但我想说,机遇是留给能坚持下去的人。如果一个人只有三分钟热度,那他一定找不到成功的钥匙。因为他找不到通往成功的机遇。只有善始善终的人,才能发现机遇并运用机遇。为自己的成功创造可能。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值