安卓飛機大戰源碼,面向對象思想,多線程,包含註釋.接口等運用

安卓飛機大戰源碼,面向對象思想,多線程,包含註釋.


最近閒來無事看看安卓的api做一個飛機大戰.
如有轉發需聲明作者:吳年和.
本代碼無償開源.
圖片與聲音我就不提供了.

package com.example.planebigwar.entity;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import com.example.planebigwar.R;
import com.example.planebigwar.interfaces.Awarde;
import com.example.planebigwar.interfaces.Score;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @Author: 吳年和
 * @DATE: 2020/04/14 16:00:00
 * 繪畫世界類
 * 將所有的繪畫或功能在此類中實現
 */
public class PaintWorld extends View implements Runnable {

    public static final short START = 0;//遊戲開始狀態
    public static final short RUN = 1;//遊戲運行狀態
    public static final short PAUSE = 2;//遊戲暫停狀態
    public static final short OVER = 3;//遊戲結束狀態
    public static float SCREEN_HEIGHT, SCREEN_WIDTH;//屏幕寬高
    public static float scale;//比例屏幕係數
    public static short state = START;//遊戲當前狀態
    public static int score = 0;//顯示的分數
    public static int life = 30;//顯示的分數
    private static boolean gameOnOff = true;
    private static long number = 0;//運行次數
    private static Timer timer = new Timer();//時間對象
    private Resources res = getResources();//畫對象需要
    private Random random = new Random();//隨機數
    private Hero hero;//英雄對象
    private Sky sky;//天空對象
    private Start start;//開始對象
    private Pause pause;//暫停對象
    private Over over;//結束對象
    private Font scoreText;//分數對象
    private Font lifeText;//生命對象
    //private Music music;//音樂對象

    /**
     * 儲存敵人與子彈
     */
    private List<FlyObj> enemys = Collections.synchronizedList(new LinkedList<FlyObj>()),
            bullets = Collections.synchronizedList(new LinkedList<FlyObj>());

    /**
     * 繼承View所需的構造器
     *
     * @param context Activity調用時可直接傳入this
     */
    public PaintWorld(Context context) {
        super(context);
        /*
         * 設置背景顏色
         */
        setBackgroundColor(Color.BLACK);
        /*
         * 獲取設備的屏幕寬高信息
         */
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        SCREEN_HEIGHT = dm.heightPixels + (dm.heightPixels / 12);
        SCREEN_WIDTH = dm.widthPixels;

        //屏幕縮放比係數
        scale = (float) (Math.sqrt(SCREEN_HEIGHT * SCREEN_WIDTH) / Math.sqrt(480 * 800));

        /*
         * 實例化初始對象
         */
        start = new Start(800.0f, 480.0f, 0, 0, 0, 1, res);
        pause = new Pause(800.0f, 480.0f, 0, 0, 0, 1, res);
        over = new Over(800.0f, 480.0f, 0, 0, 0, 1, res);
        sky = new Sky(800.0f, 480.0f, 0, 0, 0, 1, res);
        hero = new Hero(139.0f, 97.0f, SCREEN_WIDTH / 2 - 97 * scale / 2, (float) (SCREEN_HEIGHT * 0.7), life, 0, res);
        scoreText = new Font(20, 50, res);
        lifeText = new Font(20, 100, res);

        //music = new Music(context);

        /*
         * 添加事件控制玩家飛機
         */
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent event) {
                switch (event.getAction()) {

                    case MotionEvent.ACTION_DOWN:
                    case MotionEvent.ACTION_MOVE:
                        switch (state) {
                            case RUN:
                                hero.coordinate(event.getRawX(), event.getRawY());
                                break;
                            case START:
                                state = RUN;
                                break;
                            case PAUSE:
                                state = RUN;
                                break;
                            case OVER:
                                score = 0;
                                number = 0;
                                hero = new Hero(139.0f, 97.0f, SCREEN_WIDTH / 2 - 97 * scale / 2, (float) (SCREEN_HEIGHT * 0.7), life, 0, res);
                                enemys = Collections.synchronizedList(new LinkedList<FlyObj>());
                                bullets = Collections.synchronizedList(new LinkedList<FlyObj>());
                                state = START;
                                gameOnOff = true;
                                break;
                        }
                }
                return true;
            }
        });
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /*
         * 畫上各類角色
         * 使用方法與swing paint一致
         */
        sky.paintObj(canvas);
        switch (state) {
            case RUN:
                if (!hero.isRemove())
                    hero.paintObj(canvas);
                paint(bullets, canvas);
                paint(enemys, canvas);
                break;
            case START:
                start.paintObj(canvas);
                break;
            case PAUSE:
                pause.paintObj(canvas);
                break;
            case OVER:
                over.paintObj(canvas);
                break;
        }
        scoreText.paintObj(canvas);
        lifeText.paintObj(canvas);
    }

    /**
     * 畫集合內的對象
     * 遍歷對象
     *
     * @param objs
     * @param canvas
     */
    private synchronized void paint(List<FlyObj> objs, Canvas canvas) {
        for (int i = 0; i < objs.size(); i++) {
            objs.get(i).paintObj(canvas);
        }
    }

    /**
     * 添加對象
     */
    private void addEnemyAction() {
        if (number % 30 == 0) {
            int random = this.random.nextInt(100);
            if (random < 1)
                enemys.add(new Star(res));

            else if (random < 20)
                enemys.add(new BigPlane(res));

            else
                enemys.add(new SmallPlane(res));
        }
    }

    /**
     * 判斷物體是否越界
     */
    private void transboundary() {
        setRemove(enemys);
        setRemove(bullets);
        remove(enemys);
        remove(bullets);
    }

    /**
     * 設置移除跨界對象
     *
     * @param objs
     */
    private void setRemove(List<FlyObj> objs) {
        for (int i = 0; i < objs.size(); i++) {
            if (objs.get(i).getY() > (SCREEN_HEIGHT * scale) || objs.get(i).getY() < 0 - objs.get(i).getHeight() ||
                    objs.get(i).getX() < 0 - objs.get(i).getWidth() || objs.get(i).getX() > (SCREEN_WIDTH * scale)) {
                objs.get(i).setREMOVE();
            }
        }
    }

    /**
     * 移除對象
     *
     * @param objs
     */
    private synchronized void remove(List<FlyObj> objs) {

        for (int i = 0; i < objs.size(); i++) {
            if (objs.get(i).isRemove()) {
                objs.remove(i);
                return;
            }
        }
    }

    /**
     * 添加子彈
     */
    private void addBulletAction() {
        Bullet[] bullets = hero.nextBullets();
        if (number % 10 == 0 && hero.isLive()) {
            for (int i = 0; i < bullets.length; i++) {
                this.bullets.add(bullets[i]);
            }
        }
    }

    /**
     * 開始運行
     */
    @Override
    public void run() {
        new Thread(new SkyMove()).start();
        new Thread(new ObjMove()).start();
        //new Thread(music).start();

        while (true) {
            scoreText.setText("Score: " + score);
            lifeText.setText("Life: " + hero.life);
            switch (state) {
                case RUN:
                    checkGameOverAction();
                    addBulletAction();
                    addEnemyAction();
                    transboundary();
                    hitHandler();
                    break;
                case START:
                    break;
                case PAUSE:
                    break;
                case OVER:
                    break;
            }
            try {
                number++;
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    //檢測遊戲結束
    public void checkGameOverAction() {
        //如果英雄機生命值爲0
        if (hero.isRemove() && gameOnOff) {
            gameOnOff = false;
            //遊戲結束
            timer.schedule(new TimerTask() {
                public void run() {
                    state = OVER;
                    gameOnOff = true;
                }
            }, 1500);
        }
    }

    /**
     * 碰撞處理
     */
    private void hitHandler() {
        for (int i = 0; i < enemys.size(); i++) {
            for (int j = 0; j < bullets.size(); j++) {
                /**
                 * 敵機碰到子彈
                 */
                if (enemys.get(i).hit(bullets.get(j)) && enemys.get(i).isLive() && bullets.get(j).isLive()) {
                    enemys.get(i).reduceHP(bullets.get(j).life);
                    bullets.get(j).reduceHP(enemys.get(i).life);
                    if (enemys.get(i) instanceof Score && enemys.get(i).isDead()) {
                        Score s = (Score) enemys.get(i);
                        score += s.getScore();
                    } else if (enemys.get(i) instanceof Awarde && enemys.get(i).isDead()) {
                        Awarde a = (Awarde) enemys.get(i);
                        int type = a.getAwardType();
                        if (type == hero.getBulletType()){
                            type = 0;
                        }
                        switch (type) {
                            case Awarde.LIVE:
                                hero.addLive();
                                break;
                            case Awarde.BULLET_DOUBLE:
                                hero.addBulletDouble();
                                break;
                            case Awarde.BULLET_SHOTGUN:
                                hero.addBulletShotgun();
                                break;
                        }
                    }
                }
            }

            /**
             * 敵機碰到英雄
             */
            if (enemys.get(i).hit(hero) && enemys.get(i).isLive() && hero.isLive()) {
                /**
                 * 判斷屬於獎勵還是分數接口
                 */
                if (enemys.get(i) instanceof Score) {
                    hero.reduceHP(enemys.get(i).life);
                    Score s = (Score) enemys.get(i);
                    score += s.getScore();
                } else if (enemys.get(i) instanceof Awarde) {
                    Awarde a = (Awarde) enemys.get(i);
                    int type = a.getAwardType();
                    /**
                     * 如果吃到了相同的子彈就讓他變成生命
                     */
                    if (type == hero.getBulletType()){
                        type = 0;
                    }
                    switch (type) {
                        case Awarde.LIVE:
                            hero.addLive();
                            break;
                        case Awarde.BULLET_DOUBLE:
                            hero.addBulletDouble();
                            break;
                        case Awarde.BULLET_SHOTGUN:
                            hero.addBulletShotgun();
                            break;
                        default:
                            hero.addBulletDefault();
                    }
                }
                enemys.get(i).reduceHP(hero.life);
            }
        }
    }

    /**
     * 遍歷移動
     *
     * @param objs
     */
    private void step(List<FlyObj> objs) {
        for (int i = 0; i < objs.size(); i++) {
            objs.get(i).step();
        }
    }

    /**
     * 對象移動獨立線程
     */
    private class ObjMove implements Runnable {

        @Override
        public void run() {
            while (true) {
                switch (state) {
                    case RUN:
                        step(enemys);
                        step(bullets);
                        break;
                    case START:
                        break;
                    case PAUSE:
                        break;
                    case OVER:
                        break;
                }
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 天空移動獨立線程
     */
    private class SkyMove implements Runnable {

        @Override
        public void run() {
            while (true) {
                switch (state) {
                    case RUN:
                        sky.step();
                        break;
                    case START:
                        break;
                    case PAUSE:
                        break;
                    case OVER:
                        break;
                }
                try {
                    postInvalidate();
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 音樂類,及耗性能
     */
    public class Music implements Runnable {
        MediaPlayer mediaPlayer;

        private Music(Context context) {
            mediaPlayer = new MediaPlayer();
            mediaPlayer = MediaPlayer.create(context, R.raw.bgm);
        }

        public Music(Context context, int id) {
            mediaPlayer = new MediaPlayer();
            mediaPlayer = MediaPlayer.create(context, id);
        }

        @Override
        public void run() {
            mediaPlayer.start();
        }
    }
}

package com.example.planebigwar;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

import com.example.planebigwar.entity.PaintWorld;

/**
 * @Author: 吳年和
 * @DATE: 2020/04/14 16:00:00
 */
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        PaintWorld paintWorld = new PaintWorld(this);
        setContentView(paintWorld);

        //隱藏標題欄
        getSupportActionBar().hide();
        new Thread(paintWorld).start();

    }


}

package com.example.planebigwar.entity;

import android.content.res.Resources;
import android.graphics.Bitmap;

import com.example.planebigwar.R;
import com.example.planebigwar.interfaces.Score;

public class Start extends FlyObj implements Score {
    /**
     * 比較懶這裏可以是使用集合保存圖片做出爆炸效果
     */
    private static Bitmap img;

    {
        img = getImage(R.mipmap.start);
    }

    public Start(float height, float width, float x, float y, int life, float step, Resources resources) {
        super(height, width, x, y, life, step, resources);
    }

    public Start(Resources resources) {
        super(PaintWorld.SCREEN_HEIGHT, PaintWorld.SCREEN_WIDTH, 0, 0, 1, 0, resources);
    }

    @Override
    protected Bitmap readImage() {
        if (isDead()) {
            state = REMOVE;
        }
        return img;
    }

    @Override
    public int getScore() {
        return 0;
    }
}

package com.example.planebigwar.entity;

import android.content.res.Resources;
import android.graphics.Bitmap;

import com.example.planebigwar.R;
import com.example.planebigwar.interfaces.Awarde;

public class Star extends FlyObj implements Awarde {
    private static Bitmap img;
    private float stepX = step;
    private float stepY = step;
    private int awardeType;
    private int awardeRange = Awarde.awardMaxNumber + 2;

    {
        img = getImage(R.mipmap.bee0);
    }

    /**
     * 基類的構造器
     *
     * @param height    對象的高
     * @param width     對象的寬
     * @param x         對象的X
     * @param y         對象的Y
     * @param life      對象的生命值
     * @param step
     * @param resources
     */
    public Star(float height, float width, float x, float y, int life, float step, Resources resources) {
        super(height, width, x, y, life, step, resources);
        this.awardeType = random.nextInt(awardeRange);
    }

    public Star(Resources resources) {
        super(60, 60, (float) random.nextInt((int) (PaintWorld.SCREEN_WIDTH - 60 * PaintWorld.scale)), -60 * PaintWorld.scale, 30, 1, resources);
        this.awardeType = random.nextInt(awardeRange);
    }

    @Override
    protected Bitmap readImage() {
        if (isDead()) {
            state = REMOVE;
            //return image[2];
        }
        return img;
    }

    @Override
    public int getAwardType() {
        return awardeType;
    }

    @Override
    public void step() {
        setY(y += stepY);
        setX(x += stepX);
        if (x > PaintWorld.SCREEN_WIDTH - width || x <= 0)
            stepX *= -1;
    }
}

package com.example.planebigwar.entity;

import android.content.res.Resources;
import android.graphics.Bitmap;

import com.example.planebigwar.R;
import com.example.planebigwar.interfaces.Score;

public class SmallPlane extends FlyObj implements Score {
    private static Bitmap img;

    {
        img = getImage(R.mipmap.airplane0);
    }

    public SmallPlane(float height, float width, float x, float y, int life, float step, Resources resources) {
        super(height, width, x, y, life, step, resources);
    }

    public SmallPlane(Resources resources) {
        super(50f, 48f, (float) random.nextInt((int) (PaintWorld.SCREEN_WIDTH - 48 * PaintWorld.scale)), -50 * PaintWorld.scale, 2, 3, resources);
    }

    @Override
    protected Bitmap readImage() {
        if (isDead()) {
            state = REMOVE;
            //return image[2];
        }
        return img;
    }


    @Override
    public int getScore() {
        return 1;
    }
}

package com.example.planebigwar.entity;


import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.RectF;

import com.example.planebigwar.R;

public class Sky extends FlyObj {
    private static Bitmap img;
    /**
     * 第二天空位置
     */
    protected RectF r1;

    {
        img = getImage(R.mipmap.background0);
    }

    public Sky(float height, float width, float x, float y, int life, float step, Resources resources) {
        super(height, width, x, y, life, step, resources);
        r1 = new RectF();
        r1.top = y - height * PaintWorld.scale;
        r1.bottom = step;
        r1.left = x;
        r1.right = x + width * PaintWorld.scale;

    }


    @Override
    protected Bitmap readImage() {
        return img;
    }


    @Override
    public void paintObj(Canvas canvas) {
        canvas.drawBitmap(readImage(), null, r, p);
        canvas.drawBitmap(readImage(), null, r1, p);

    }


    /**
     * 重寫移動方法
     */
    @Override
    public void step() {
        r.top += step;
        r.bottom += step;
        r1.top += step;
        r1.bottom += step;
        if (r.top >= height) {
            r.top = -height;
            r.bottom = 3;
        }
        if (r1.top >= height) {
            r1.top = -height;
            r1.bottom = 3;
        }
    }
}

package com.example.planebigwar.entity;

import android.content.res.Resources;
import android.graphics.Bitmap;

import com.example.planebigwar.R;
import com.example.planebigwar.interfaces.Score;

public class Pause extends FlyObj implements Score {
    /**
     * 比較懶這裏可以是使用集合保存圖片做出爆炸效果
     */
    private static Bitmap img;

    {
        img = getImage(R.mipmap.pause);
    }

    public Pause(float height, float width, float x, float y, int life, float step, Resources resources) {
        super(height, width, x, y, life, step, resources);
    }

    public Pause(Resources resources) {
        super(PaintWorld.SCREEN_HEIGHT, PaintWorld.SCREEN_WIDTH, 0, 0, 1, 0, resources);
    }

    @Override
    protected Bitmap readImage() {
        if (isDead()) {
            state = REMOVE;
        }
        return img;
    }

    @Override
    public int getScore() {
        return 0;
    }
}

package com.example.planebigwar.entity;

import android.content.res.Resources;
import android.graphics.Bitmap;

import com.example.planebigwar.R;
import com.example.planebigwar.interfaces.Score;

public class Over extends FlyObj implements Score {
    /**
     * 比較懶這裏可以是使用集合保存圖片做出爆炸效果
     */
    private static Bitmap img;

    {
        img = getImage(R.mipmap.gameover);
    }

    public Over(float height, float width, float x, float y, int life, float step, Resources resources) {
        super(height, width, x, y, life, step, resources);
    }

    public Over(Resources resources) {
        super(PaintWorld.SCREEN_HEIGHT, PaintWorld.SCREEN_WIDTH, 0, 0, 1, 0, resources);
    }

    @Override
    protected Bitmap readImage() {
        if (isDead()) {
            state = REMOVE;
        }
        return img;
    }

    @Override
    public int getScore() {
        return 0;
    }
}

package com.example.planebigwar.entity;

import android.content.res.Resources;
import android.graphics.Bitmap;

import com.example.planebigwar.R;

import java.util.TimerTask;

public class Hero extends FlyObj {
    private static Bitmap img;

    /**
     * 子彈類型
     */
    private int bulletType = 0;

    /**
     * 子彈時間開關
     */
    private boolean bulletTimeOnOff = true;

    public int getBulletType() {
        return bulletType;
    }

    public void setBulletType(int bulletType) {
        this.bulletType = bulletType;
    }

    {
        img = getImage(R.mipmap.hero0);
    }

    /**
     * 英雄的實體類
     *
     * @param height
     * @param width
     * @param x
     * @param y
     * @param life
     * @param resources
     */
    public Hero(float height, float width, float x, float y, int life, float step, Resources resources) {
        super(height, width, x, y, life, step, resources);
    }

    /**
     * 英雄發射的子彈
     *
     * @return
     */
    public Bullet[] nextBullets() {
        /**
         * 十五秒後自動變回初始子彈
         */
        if (bulletType != 0 && bulletTimeOnOff){
            bulletTimeOnOff = false;
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    bulletType = 0;
                    bulletTimeOnOff = true;
                }
            },15000);
        }
        Bullet[] bullets = null;
        float middle = x + width / 2 - 12;
        switch (bulletType) {

            /**
             * 雙道彈
             */
            case 1:
                bullets = new Bullet[2];
                bullets[0] = new Bullet(middle - 50, y + 100, resources);
                bullets[1] = new Bullet(middle + 50, y + 100, resources);
                break;

            /**
             * 散彈
             */
            case 2:
                bullets = new Bullet[3];
                bullets[0] = new Bullet(middle, y + 100, (float) 1.5, resources);
                bullets[1] = new Bullet(middle, y + 100, 0, resources);
                bullets[2] = new Bullet(middle, y + 100, (float) -1.5, resources);
                break;

            /**
             * 默認子彈0
             */
            default:
                bullets = new Bullet[1];
                bullets[0] = new Bullet(middle, y, resources);
                break;
        }
        return bullets;
    }

    @Override
    protected Bitmap readImage() {
        if (isDead()) {
            state = REMOVE;
            //return image[2];
        }
        return img;
    }

    /**
     * 座標
     *
     * @param x
     * @param y
     */
    public void coordinate(float x, float y) {
        setX(x - this.width / 2);
        setY((float) (y - this.height * 0.7));
    }

    @Override
    public void step() {
    }

    public void addLive() {
        this.life += 5;
    }

    public void addBulletDefault() {
        this.bulletType = 0;
    }

    public void addBulletDouble() {
        this.bulletType = 1;
    }

    public void addBulletShotgun() {
        this.bulletType = 2;
    }
}

package com.example.planebigwar.entity;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;

public class Font extends FlyObj {
    private int color = 0xffffffff;
    private String text = "";


    /**
     * 基類的構造器
     *
     * @param height    對象的高
     * @param width     對象的寬
     * @param x         對象的X
     * @param y         對象的Y
     * @param life      對象的生命值
     * @param step
     * @param resources
     */
    public Font(float height, float width, float x, float y, int life, float step, Resources resources) {
        super(height, width, x, y, life, step, resources);
    }

    public Font(String text, float height, float width, float x, float y, int life, float step, Resources resources) {
        super(height, width, x, y, life, step, resources);
        this.text = text;
    }

    public Font(String text, Resources resources) {
        super(20, 100, 20, 50, 1, 0, resources);
        this.text = text;
        this.p.setTextSize(50);
        this.p.setColor(color);
    }

    public Font(String text, float x, float y, Resources resources) {
        super(20, 100, x, y, 1, 0, resources);
        this.text = text;
        this.p.setTextSize(50);
        this.p.setColor(color);
    }

    public Font(float x, float y, Resources resources) {
        super(20, 100, x, y, 1, 0, resources);
        this.p.setTextSize(50);
        this.p.setColor(color);
    }

    public Font(String text, int color, Resources resources) {
        super(20, 100, 20, 50, 1, 0, resources);
        this.text = text;
        this.p.setTextSize(50);
        this.color = color;
        this.p.setColor(color);
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setColor(int color) {
        this.p.setColor(color);
    }

    @Override
    protected Bitmap readImage() {
        return null;
    }

    /**
     * 畫對象
     *
     * @param canvas
     */
    @Override
    public void paintObj(Canvas canvas) {
        canvas.drawText(text, x, y, p);
    }
}

package com.example.planebigwar.entity;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;

import java.util.Random;
import java.util.Timer;

/**
 * 所有對象的基類
 */
public abstract class FlyObj {
    protected final static short LIVE = 0;
    protected final static short DEAD = 1;
    protected final static short REMOVE = 2;
    protected static Random random = new Random();
    protected static Timer timer = new Timer();
    protected static Resources resources;

    public short state = LIVE;
    /**
     * 角色位置
     * 函數需要
     */
    protected RectF r = new RectF();

    /**
     * 顏色等屬性
     * 函數需要
     */
    protected Paint p = new Paint();
    /**
     * 寬,高,生命
     */
    protected int life = 0;
    protected float height, width, x, y, step = 3f;

    /**
     * 基類的構造器
     *
     * @param height    對象的高
     * @param width     對象的寬
     * @param x         對象的X
     * @param y         對象的Y
     * @param life      對象的生命值
     * @param resources
     */
    public FlyObj(float height, float width, float x, float y, int life, float step, Resources resources) {
        this.height = height * PaintWorld.scale;
        this.width = width * PaintWorld.scale;
        this.x = x;
        this.y = y;
        this.life = life;
        FlyObj.resources = resources;
        this.step = step;
        setX(x);
        setY(y);
    }

    /**
     * 獲取圖片
     *
     * @param id
     * @return
     */
    protected static Bitmap getImage(Integer id) {
        return BitmapFactory.decodeResource(resources, id);
    }

    public void setLIVE() {
        state = LIVE;
    }

    public void setDEAD() {
        state = DEAD;
    }

    public void setREMOVE() {
        state = REMOVE;
    }

    /**
     * 判斷是否活着
     *
     * @return
     */
    public boolean isLive() {
        return state == LIVE;
    }

    /**
     * 判斷是否死亡
     *
     * @return
     */
    public boolean isDead() {
        return state == DEAD;
    }

    /**
     * 判斷是否移除
     *
     * @return
     */
    public boolean isRemove() {
        return state == REMOVE;
    }

    /**
     * 獲取角色高度
     *
     * @return
     */
    public float getHeight() {
        return height;
    }

    /**
     * 更新角色高度.
     * 高度不允許爲負數,如爲負數則默認設置爲0.
     *
     * @param height
     */
    public void setHeight(int height) {
        if (height >= 0)
            this.height = height;
        else
            this.height = 0;
    }

    /**
     * 獲取角色寬度
     *
     * @return
     */
    public float getWidth() {
        return width;
    }

    /**
     * 更新角色寬度.
     * 寬度不允許爲負數,如爲負數,則默認設置爲0
     *
     * @param width
     */
    public void setWidth(int width) {
        if (width >= 0)
            this.width = width;
        else
            this.width = 0;
    }

    /**
     * 獲取生命值
     *
     * @return
     */
    public int getLife() {
        return life;
    }

    /**
     * 設置生命值生命值不允許爲負數
     *
     * @param life
     */
    public void setLife(int life) {
        if (life >= 0)
            this.life = life;
        else
            this.life = 0;
    }

    /**
     * 獲取X位置
     *
     * @return
     */
    public float getX() {
        return this.r.left;
    }

    /**
     * 設置X位置
     *
     * @param x
     */

    public void setX(float x) {
        this.x = x;
        this.r.left = x;
        this.r.right = x + this.width;
    }

    /**
     * 獲取Y位置
     *
     * @return
     */
    public float getY() {
        return this.r.top;
    }

    /**
     * 設置Y位置
     *
     * @param y
     */
    public void setY(float y) {
        this.y = y;
        this.r.top = y;
        this.r.bottom = y + this.height;
    }

    /**
     * 獲取圖片
     * 重寫否自動調用
     *
     * @return
     */
    protected abstract Bitmap readImage();

    /**
     * 畫對象
     *
     * @param canvas
     */
    public void paintObj(Canvas canvas) {
        canvas.drawBitmap(readImage(), null, r, p);
    }

    /**
     * 移動對象
     */
    public void step() {
        setY(y + step);
    }

    /**
     * 扣血
     *
     * @param hp
     */
    public void reduceHP(int hp) {
        setLife(this.life - hp);
        if (this.life <= 0)
            setDEAD();
    }

    /**
     * 碰撞
     *
     * @param obj 傳入一個要判斷的對象
     * @return 是否碰到對象
     */
    public boolean hit(FlyObj obj) {
        float x1 = this.x - obj.width;
        float x2 = this.x + this.width;
        float y1 = this.y - obj.height;
        float y2 = this.y + this.height;
        return obj.x >= x1 && obj.x <= x2 && obj.y >= y1 && obj.y <= y2;
    }

    @Override
    public String toString() {
        return "FlyObj{" +
                "height=" + height +
                ", width=" + width +
                ", life=" + life +
                ", x=" + x +
                ", y=" + y +
                '}';
    }

}

package com.example.planebigwar.entity;

import android.content.res.Resources;
import android.graphics.Bitmap;

import com.example.planebigwar.R;

public class Bullet extends FlyObj {
    private static Bitmap img;
    private float stepX = 0;

    {
        img = getImage(R.mipmap.bullet);
    }

    /**
     * 基類的構造器
     *
     * @param height    對象的高
     * @param width     對象的寬
     * @param x         對象的X
     * @param y         對象的Y
     * @param life      對象的生命值
     * @param step
     * @param resources
     */
    public Bullet(float height, float width, float x, float y, int life, float step, Resources resources) {
        super(height, width, x, y, life, step, resources);
    }

    public Bullet(float x, float y, Resources resources) {
        super(20, 8, x, y, 1, 30, resources);
    }

    public Bullet(float x, float y, float stepX, Resources resources) {
        super(20, 8, x, y, 1, 30, resources);
        this.stepX = stepX;
    }

    @Override
    protected Bitmap readImage() {
        if (isDead()) {
            state = REMOVE;
            //return image[2];
        }
        return img;
    }

    @Override
    public void step() {
        setY(y -= step);
        setX(x -= stepX);
    }
}

package com.example.planebigwar.entity;

import android.content.res.Resources;
import android.graphics.Bitmap;

import com.example.planebigwar.R;
import com.example.planebigwar.interfaces.Score;

public class BigPlane extends FlyObj implements Score {
    /**
     * 比較懶這裏可以是使用集合保存圖片做出爆炸效果
     */
    private static Bitmap img;

    {
        img = getImage(R.mipmap.bigairplane0);
    }

    public BigPlane(float height, float width, float x, float y, int life, float step, Resources resources) {
        super(height, width, x, y, life, step, resources);
    }

    public BigPlane(Resources resources) {
        super(89, 66, (float) random.nextInt((int) (PaintWorld.SCREEN_WIDTH - 66 * PaintWorld.scale)), -89 * PaintWorld.scale, 15, 2, resources);
    }

    @Override
    protected Bitmap readImage() {
        if (isDead()) {
            state = REMOVE;
            //return image[2];
        }
        return img;
    }

    @Override
    public int getScore() {
        return 5;
    }
}

package com.example.planebigwar.interfaces;

public interface Awarde {

    int awardMaxNumber = 2;

    /**
     * 獎勵生命
     */
    int LIVE = 0;

    /**
     * 獎勵雙道子彈
     */
    int BULLET_DOUBLE = 1;

    /**
     * 獎勵散彈
     */
    int BULLET_SHOTGUN = 2;

    /**
     * 獲取獎勵類型
     *
     * @return
     */
    int getAwardType();
}

package com.example.planebigwar.interfaces;

public interface Score {
    int getScore();
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章