Android studio 飛機大戰項目思路和代碼

整體思路

先背景

繪製玩家飛機,玩家飛機隨觸摸點移動

繪製boss飛機,自動移動

繪製子彈,分別從玩家飛機和boss飛機發射

繪製爆裝效果,由子彈觸發

繪製血量,玩家血量爲0觸發死亡畫面,boss血量爲零觸發通過

繪製開始界面,點擊開機進入遊戲



1.如何繪製滾動的背景圖片

第一張圖y座標往下遞減實現滾動,

第二張圖的底部座標等於第一張圖的頂部座標,當第一張圖片的頂部座標大於屏幕,令其底部座標等於第二張圖的頂部座標實現循環滾動。

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


2.如何繪製飛機

 用canvas調用drawBitmap

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+height){
                noCollision = true;
                hp--;
                return true;
            }
        }
        return false;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getWidth() {
        return width;
    }
}


3.如何繪製子彈

 用canvas調用drawBitmap

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;
               if (y < 0) {
                   isDead = true;
               }
               break;
       }
    }

    public boolean isDead() {
        return isDead;
    }
    public Bitmap getBitmap(){
        return bitmap;
    }
    public int getX(){
        return x;
    }

    public int getY() {
        return y;
    }
}

4.如何判斷碰撞

子彈的左右x座標在飛機左右x座標裏面

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

5.如何繪製爆裝效果

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

public class Boom {
    private Bitmap bitmap;
    private int x,y;
    private int totalFrame;
    private int currentFrame;//當前顯示的第幾幅畫面
    private int frameH,frameW;
    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;
        frameH = bitmap.getHeight();
        frameW = bitmap.getWidth()/totalFrame;
    }
    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.如何添加音效

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);
        s1 = soundPool.load(context,R.raw.shoot,1);
        s2 = soundPool.load(context,R.raw.explosion2,1);
    }
    public void playSound(int s){
        switch (s){
            case 1:

                soundPool.play(s1,1,1,1,0,1.0f);
                break;
            case 2:
                soundPool.play(s2,1,1,1,0,1.0f);
                break;
        }


    }
}


定義變量時常常用到封裝。

需要用某個類的功能但又想擴展一些功能,可以繼承那個類。

public class MySurfaceView extends SurfaceView 

實現接口

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable 

我的收穫與感悟

首先是對java有了更深的理解,但主要學到了不少道理,覺得很受用。尤其學習方法,

最後感受,真應該先跟着老師走,優先老師的任務,老師要求的先全部完成。

爲什麼?不是說自己學哪裏不對,有不懂的自己去查去看毫無問題,但先理解老師要求理解的,因爲一旦和老師脫節,老師的之後佈置的任務就很難完成,因爲任務是老師教的內容的實踐。考覈也會很煩,因爲考的也是老師讓我們理解掌握的,結果往往就是爲了任務和考覈花大量時間精力補老師講的內容。

Java的內容很多,任何一門學科的全部內容都很多,先完成老師的要求,再去擴展。

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