飞机大战游戏详解

1.整体实现思路

在我设计的整个游戏中,把飞机大战这个项目总共可以分为三个对象:第一个是飞机,飞机又可以分为我方飞机,敌方飞机和敌方boss飞机;第二个是背景,为了体现出飞机的飞行,需要用到背景的滚动,而实现背景的滚动又要使用第一个跟第二个背景的衔接,才能完美实现飞行效果;第三个是子弹,既然是飞机大战,肯定需要双方飞机的射击大战,所以在绘制子弹后,便要考虑到子弹与飞机的碰撞,就会考虑到x,y轴的变化,长度和宽度,以及碰撞的效果。其他的便是优化你的程序,比如给这个游戏加一个bgm,比如我方飞机加一些道具。

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

定义y轴y1,y2,当第一张图片大于等于屏幕长度时,移动到第二张图片的顶部

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.如何绘制飞机

创建飞机类MyPlane

可以在类中添加你所需要的效果(比如击中闪烁无敌等)

最后别忘了在MySurfaceView中的run方法中调用

 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);
        }

    }


4.如何绘制子弹

创建子弹Bullet类:可以在里面定义子弹的属性跟玩家飞机子弹和boss机子弹

在Mysurfaceview中调用
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;
        }
    }

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

子弹与boss碰撞:

当玩家飞机子弹面积范围接触到BOSS飞机面积范围时产生碰撞效果,boss血量减少
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;

    }

飞机与飞机碰撞:

当玩家飞机的上方范围接触到BOSS飞机底端范围实现碰撞,血量减少

  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(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+width>bossPlane.getX()+bossPlane.getFrameW()){
                    noCollision = true;
                    if (hp>0){
                        hp--;
                    }

                    return true;

                }
            }

        }
        return false;
    }


6.如何绘制爆炸效果

创建一个爆炸类(boom)

Mysurfaceview,玩家飞机子弹接触Boss飞机范围后实现爆炸效果

爆炸效果由图片剪裁形成

  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();

    }
if (bossPlane.isCollison(bulletVector.elementAt(i))) {  
                             gameSoundPool.playSound(3);  
                             Boom boom = new Boom(BitmapFactory.decodeResource(getResources(), mipmap.boom), bossPlane.getX()+bossPlane.getFrameW()/3, bossPlane.getY()+bossPlane.getFrameH()/4, 7);  
  
                             boomVector.add(boom);  
  
                         }  


7.如何添加音效

在res中创建一个raw来放置音频文件,在MySurfaceView中用switch语句调用

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.哪些地方用到封装,继承,多态,方法重载,接口等

封装:每个子类中都实现了不同属性的封装

继承:MyPlane与BossPlane类的位置方法在MySurfaceView中体现了继承

多态:不同种飞机的不同血量范围

重载:玩家飞机与boss飞机相撞

接口:添加音效



9.我的收获与感悟

收获:最大的收获估计就是从之前的一点不懂,到现在能够懂一点,我感觉这是我最大的收获。

其次的话,应该是对编程开始感兴趣了,通过这次项目,让自己了解到,原来自己也是可以在老师的指导下,可以完成自己的项目,不至于像以前一样,无从下手。

感悟:这次的项目,我个人感觉这是一个适合新手来试试编程的水的项目,因为这一个项目,基本可以让你复习并且巩固你java的基础,而且,感觉这个项目的拓展性很强,让你可以运用自己的创新性思维,用程序来实现你的想法,然后制作你自己喜欢的游戏,充分体验编程的乐趣。


  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值