五月三十一日学习日志(飞机大战)

飞机大战

1.整体实现思路

飞机大战,一个小游戏,怎么实现这个游戏呢,首先要有完整的思路,选好背景,然后设置背景,实现两张背景的循环,达成背景的循环滚动,第二步,加上一个玩家飞机,首先给他赋予初始位置,然后给玩家飞机Touch,实现玩家飞机能按照手指的触摸位置来进行移动,第三步,Boss飞机,同样的道理,与玩家飞机的差别只不过少了触摸移动,在背景的上方给Boss飞机进行判断,实现飞机的左右移动,第四步,给飞机加上子弹,玩家飞机和Boss飞机子弹是同一个道理,创建一个speed给它赋值,这是子弹的速度,用speed++进行子弹的加速,再定义一个ISDEAD,进行子弹的判断,第五步,给子弹加声音,在子弹加声音的前提下要先进行判断,判断当子弹撞到飞机的时候的各种不同的反应,飞机撞到飞机时候的反应,比如玩家飞机和Boss飞机的血量的减少,以及飞机无敌时间,然后就是赋予碰撞时的声音。大体就差不多这么多,如果还有疑问可以留言。

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

首先定义图片的y,y1,Bitmap,给这三个值赋予构造方法,当然在这之前你得有个“画板”和“画笔”,一定要记得锁定画板和解锁画板,然后在逻辑方法中进行判断,给y和y1进行++实现背景的滚动,然后你会发现两张背景不会衔接到一起,所以这个时候就得换一种判断方法,当你的第一张图循环结束,把第二张图放在后面继续进行滚动,第一张图立马放到第二张图后面接着循环,这样就会有一种一直在循环的感觉。
下面是背景这一部分的代码:

/**
 * 背景
 */

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


public class BackGroud {
    private int y1;
    private int y2;
    private  Bitmap bitmap;

    public BackGroud(Bitmap bitmap){
        this.bitmap = bitmap;
        y1 = 0;
        y2 = y1-bitmap.getHeight();


    }


    public void draw(Canvas canvas){
        logic();
        Paint paint = new Paint();
        canvas.drawBitmap(bitmap,0, y1,paint);
        canvas.drawBitmap(bitmap,0, y2,paint);


    }
    public void logic(){ //逻辑方法
        y1+=10;
        y2+=10;
        if(y1>=bitmap.getHeight()){
            y1 = y2-bitmap.getHeight(); //移动在第二张上面

        }
        if(y2>=bitmap.getHeight()){
            y2=y1-bitmap.getHeight();

        }
    }



}

3.如何绘制飞机

首先给飞机定义一个初始位置,在屏幕的下面中间,给飞机X,Y值定义成屏幕的X最下方以及Y的中间,当然,这样你会发现飞机不在正中间的位置,因为这里的XY是飞机和屏幕的左上角的位置,这时候的飞机在中间偏右这个位置,所以你要减去半个飞机的宽度(这里是飞机的宽度,不是说X的一半)才能到达正中心,还有就是给飞机定义一个初始血量Hp为3,以便于后面的使用,还有就是无敌状态,我会在下面进行介绍,然后用Canvas的方法调用到飞机的图片,最后再在主类中调用Myplane中的draw。
代码如下:

/**
*玩家飞机
*/
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.bitmapHp = bitmapHp;
        this.bitmap = bitmap;
        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_start = 3;
        }
        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);//HP位置
        }


    }

    public void touchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            float ex = event.getX();
            float ey = 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;
                }
            }
        }
    }
    //我方飞机与boss子弹
    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;

    }
    //我方飞机与boss
    public boolean Attack(Bossplane bossplane) {
        if (noCollision) {
            return false;

        }
        if(y<bossplane.getY()+bossplane.getFrameH()&&y+height>bossplane.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;
    }



    public int getX() { return x; }

    public int getY() { return y; }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }
}

4.如何绘制子弹

同样和上面一样,三要素写好,构造方法写好,这里与上面多了一个speed,是给子弹赋予速度,还有就是要有子弹消失,不然,子弹打出去消失不了。
其中主要代码为:

public void logic() {
        switch (type){
            //玩家子弹
            case 0:
                y -= speed;
                if (y < 0) {
                    isDead = true;

                }
                break;
            //boos子弹
            case 1:
                y += speed;
                if (y < 0) {
                    isDead = true;

                }
                break;
        }

当然不可能只有这么多,这只是部分代码,最后的代码会在最后公布。

5.如何判断碰撞

1.飞机与子弹碰撞

这里就要说到主要类MySurfaceView了,这个类主要要先实现继承和接口,然后碰撞主要的内容就是判断,当飞机的坐标和子弹的坐标重合一样的时候,就会实现玩家飞机血量的减少,来体现你的飞机已经碰撞上了,当然,条件不是那么简单,你要做好几个判断,首先先说Boss子弹和玩家飞机碰撞的时候的判断,当子弹的右边碰上飞机的左边并子弹的左边小于飞机的左边,子弹的右边小于飞机的右边,当子弹的右边大于飞机的左边并子弹的左边小于飞机的右边这个时候就是飞机与子弹的碰撞。
飞机与子弹的碰撞代码如下:

//我方飞机与boss子弹
    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;

    }

2.玩家飞机与Boss飞机碰撞

然后就是玩家飞机和Boss飞机的碰撞,这里还运用到了方法的重写,判断的条件与子弹碰撞飞机一样,只要画图来做就会觉得很简单了,所以每个判断都做个图,他们的判断条件就会一目了然。
飞机碰撞飞机代码如下:

//我方飞机与boss
    public boolean Attack(Bossplane bossplane) {
        if (noCollision) {
            return false;

        }
        if(y<bossplane.getY()+bossplane.getFrameH()&&y+height>bossplane.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;
    }

6.如何绘制爆炸效果

爆炸效果是用到了图片的裁剪,这里有运用到新知识了,爆炸的原图是有七张图来拼凑而成,这里运用到了Canvas的裁剪,在裁剪前一定要写上save和restore方法,这是画布裁剪的关键,这是画布的裁剪,不还原就会有一直裁剪你裁剪过的图,这里的裁剪主要是通过裁剪图片宽度的W,高度都是一样所以可以不用裁剪,用W来除以总个数。
代码如下:

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

public class Boom {
    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) {
        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.如何添加音效

在飞机中音效算是简单的这里用到了新的调用:this.soundPool,先让他实例化,其中给他选择音乐,还有优先级别。然后再用一个s来实现它,方便后面的调用,其中this.soundPool方法的括号里有六个位置,第一个是上面的s,第二个和第三个是左右声道,第四个是优先级别,第五个是emm我也不知道,总之写个1就是对了,第六个是速率,你播放的音乐的速率,最高是1.0所以再往上也是没用的。
以下是音乐的代码:

package com.example.lenovo.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;
    public GameSoundPool(Context context){
        this.soundPool = new SoundPool(2,AudioManager.STREAM_MUSIC,0);
        this.soundPool = new SoundPool(1,AudioManager.STREAM_MUSIC,0);
        s1 = soundPool.load(context,R.raw.shoot,1);
        s2 = soundPool.load(context,R.raw.button,1);
    }
    public void playSound(){
        soundPool.play(s1,1,1,1,1,1.0f);
        soundPool.play(s2,1,1,1,1,1.0f);
    }
}

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

1.继承和接口:

继承和接口就MySurfaceView中实现,这个类要继承SurfaceView,还要实现SurfaceHolder.Callback,Runnable的接口。

2.方法重载

在飞机和子弹,飞机与飞机的碰撞中定义了同一个类名,然而参数列表不一样,调用的时候,就按照里面的参数来进行传参。

3.多态

讲道理,好像没有多态的方法,这个。。。代码里面没有继承的父子类,所以好像没有实现多态,可能是自己忘了哪里了吧,小白实在想不到了,如果有大神可以说一下。

4.封装

封装用的就比较多了,每个类定义的变量有public型的还有private型的,public的不说了,所有类都能调用,private型的只能通过set和get方法来调用。

9.我的收获和感悟

先说说收获吧,收获肯定是有的,虽然一个月每天满课真的很累,但是真的能够学到很多东西,很多平时学不到的快捷键这些,而且还巩固了原来的知识,原来的JAVA课上学的东西真的有很多东西忘记了,通过学习巩固,和不断的每天回顾,真的记住了很多以前忘了的知识点,还有就是江哥上课,不仅仅讲的是我们所要学的知识点,还有很多人生的道理还有很多好看的名著,教了我们很多在以后道路上发展要记住的要点,所以,总的来说,这一周很充实,人生就像海绵,不断的挤压你自己,你永远不知道自己的潜力有多大。再来说说感悟,就敲代码这回事来说,本身我是个耐不住性子的人,根本不可能会在一天内敲这么多代码,而且正好实在夏天,所以脾气也很烦,每次代码写不出的时候就会很烦,很急,脾气也很差,然而江哥的课,怎么说,能够恰到好处的卡在正确的位置,跟着江哥的思路来学习,会发现,脑子里的思路会很顺畅,只要你跟着走,好好理解没有什么学不会的,世上没有什么事是学不会的,只是看你有没有努力,每个人生来都一样,没有谁比谁更有天赋,你在玩的时候别人在学习,差距就是这么来的,相对于JAVA而言每个人都一样,没有什么基础可言,没有什么C语言学的好不好,大家都是从零开始,不是说你天生就比我聪明,如果,你比我聪明你为什么会和我在一个班级。差不多了,应该就这么多了,絮絮叨叨的说了这么多,其实感悟确实挺多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值