飞机大战

飞机大战游戏详解

1.整体实现思路

先创建类,主类,子弹类,我方和敌方飞机类,背景类,血量类,爆炸类等等。

vector数组写我方小飞机和boss飞机的子弹和爆炸的效果,循环。

onTouchEvent方法移动小飞机,手指点到小飞机上,手指往哪里移动小飞机就往哪里移动,永远监听屏幕触摸事件。

小飞机与boss飞机碰撞的时候,小飞机被大boss子弹打中的时候血量会减少一。可以自由设定血量减少的时候无敌状态的时间。

画背景图,小飞机,boss飞机,血量,子弹,爆炸效果。需要用到canvas和drawBitmap。

定义了三个音效,子弹打中的时候、子弹爆炸的时候和飞机与boss战斗的时候,利用的soundpool的方法实现了。

当小飞机没有生命会显示你输掉了,boss没有血量你显示你赢了

2.如何绘制背景

定义一个 y1,y2,来确定坐标。

写出图片移动的速度。

利用logic让两张一样的图片反复循环,当第一张图片开始向下走的时候第二张图片接上去,当第一张图片彻底结束的时候,瞬间补位到第二张图片上面,依次执行下去。

package com.example.myapplication;

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

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

定义一个x,y 长度,宽度。

定义出我方飞机的血量,高度,宽度

再定义boss飞机的飞行速度,疯狂模式的速度,每隔多长时间进行一次疯狂模式,一个计时器,和boss飞机的血量

小飞机和boss飞机的代码原理类似,小飞机没有疯狂模式

package com.example.myapplication;

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

public class BossPlane {
    private Bitmap bitmap;
    private int x,y;
    private int frameW,frameH;
    private int speed=5;//boos飞机的速度
    private int crazySpeed=50;//疯狂速度
    private int count;//计数器
    private int time=500;//疯狂模式间隔
    private boolean isCrazy;

    private int bossHp = 100;
    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 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 int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getFrameW() {
        return frameW;
    }

    public int getFrameH() {
        return frameH;
    }

}
package com.example.myapplication;

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

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


    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getWidth() {
        return width;
    }
}

4.如何绘制子弹

子弹的速度为10,

用到了switch  if判断

如果子弹没有打中boss,当飞到顶面的时候就删除子弹

打出去的子弹不需要考虑x,只需要考虑y的变动,还有是否击中了boss或者没有飞出了屏幕

package com.example.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;
    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;
    }
}

5.如何判断碰撞(子弹与飞机的碰撞,飞机与飞机的碰撞)如何绘制爆炸效果

需要数组的帮助。

子弹击中boss的时候,爆炸图片分为了七部分,但不是同时显示出来,需要修一下图片,让它依次出现,当最后一个boom出现的时候就不再显示。等到下个boom出现。

package com.example.myapplication;


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

6.如何添加音效

背景音乐,新建一个raw,然后插入音乐

定义一个值为s

给s赋值

之后再调用就完成了

package com.example.myapplication;

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;

        }
    }
}

7.那个地方用到了继承,封装,接口,多态,方法重载等

MySurfaceView用到了继承

所有的类都用了封装

MySurfaceView实现了接口

没用到多态

重载在判断是boss子弹击中还是boss撞的时候用到重载

8.我的收获与感悟

经过了一个月的学习,收获颇多。原来java老师讲的非常的好,也很乐于给我们解答我们不会的疑难。可惜的是我却错过了他,在他的两个月授课中,我可以说是一点没有学到,开始两节课我还听讲,后来因为一些琐事上课就只顾着玩qq微信,和朋友聊天。上课根本就是玩。原来是小白现在还是小白。

一个月前,联想企业派了一位优秀的讲师来到我的学校,从头开始叫我们java 安卓。我心想,这次上课一定要好好的,不能再继续放纵自己不学习了。上第一节课的时候,老师讲了一些java非常基础的东西,比如八种基础类型。我原来还是不会这些的,幸好我哥哥发了一些资料给我,我看了一点。加上老师的复习巩固,我对于自己已经会的知识又复习了一遍。开始的一个星期老师知道我们学的不好,所以讲的非常的慢,这对于学习好的同学有点不公平,但我们班还是学的不好的占了大多数。所以老师还是为了我们考虑。

第二个星期,老师开始教我们做项目。一个图书馆里系统,    开始学的时候我感觉有点吃力了,加上老师让我上去改题目。我像个傻子一样站在上面什么都不会,然后艰难的说出了三个字“我不会”。那时候的感觉真的很难过。于是我便更加努力的学习图书管理系统。为的是老师再次叫我的时候我不再说出那几个字。

那些代码虽然看的明白,但是要是脱离了老师的代码模板,我感觉我写不出什么实质性的东西。可是我感觉我还是比以前有进步了,至少现在还肯自己去写,哪怕是借鉴的老师的代码。最后老师考核我们,让我们做一个和图书馆里系统差不多的自动售水机系统。老师说了不要看之前的代码,自己写。但我没有做到。虽然我看了之前的代码,但是我至少也把这个系统当差不差的写了出来。在规定的时间内也完成了任务。那是的我真的很开心。

时间过去一半,我们迎来了我们的实训一个月最大的难关,就是用以前从来没用过的android studio写一个小游戏。飞机大战。

在这不到两个星期的时间,我感觉我的状态虽然和以前一样,但是上课所听的东西却比以前难了,老师也知道,所以每次教完都留好多时间让我们自己消化。我就靠着自己上课录下来的视频,一步一步的打。最终也打了出来,但终究没有自己创新的成分再其中,感觉有瑕疵,很大的瑕疵,还是需要自己以后多练习,多理解其中的意思。

一个月的联想课程虽然结束了,但是我们的学习路程还没结束,还有好长的一段路要走。以后的日子里,我们还是需要一步一个脚印的加油。将来成功的自己会感谢以前发奋拼命的自己。

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值