《飛機大戰》安卓遊戲開發源碼(四)

本文章屬於原創性文章,珍惜他人勞動成果,轉載請註明出處: http://www.pm-road.com/index.php/2014/11/06/169/

 

前言:最 近閒來無事,而且也是因爲剛接觸安卓不久,所以萌生了以後在開發web 項目的過程中同樣開發安卓手遊,因前一段時間項目需要獨立完成了一款功能型手機app ,該App比較簡單,全是按鈕操作,也就是Activity之間的相互傳值與過渡,所以對安卓的基本知識有了一定了解,在我的印象當中,感覺安卓手遊是比 較困難的,但是有困難就要克服,所以有了開發遊戲的念頭。

 

安卓遊戲開發源碼(三)中,已經把控制的飛機顯示出來,結果如下:

 

飛機大戰

飛機大戰

 

接下來,就要把敵人的戰機也開發出來,並可以向下發射子彈。

 

在上一次的代碼中,找到MainActivity.java文件,在其屬性中添加:一個新的屬性:

 

// 敵機的圖片
    private List<ImageButton> enemyPlanes;

 

 

在initView()方法中,添加一個新的方法,用來初始化敵機

 

//初始化敵機
 initEnemyPlane();

 

 

然後把這個方法聲明出來:

/**
     * 初始化敵機
     */
    private void initEnemyPlane(){
        
        // 生成敵機數量,這裏在Util中新增了一個方法
        int enemyCount = CommonUtil.getEnemyPlaneCount();
        enemyPlanes = new ArrayList<ImageButton>();
        
        for (int i = 0; i < enemyCount; i++) {
            
            ImageButton enemyPlaneImg = new ImageButton(context);
            enemyPlaneImg.setBackgroundResource(R.drawable.enemyplane);

//敵機的橫座標也是隨機的
            int x = new Random().nextInt(windowWidth);
            enemyPlaneImg.setX(x);
            enemyPlaneImg.setY(0);
            this.addContentView(enemyPlaneImg, new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
            enemyPlanes.add(enemyPlaneImg);
            
        }
        
    }

 

在commonUtil.java中增加新的屬性和方法,用來隨機得到敵機數量

 

/** 出現最大的戰機數 */
    public static final int MAX_ENEMY_PLANE = 4;
    
    /**
     * 隨機得到飛機的數量
     * @return
     */
    public static final int getEnemyPlaneCount(){
        
        Random random = new Random();
        //隨機出現戰機的數量
        int enemyPlaneCount = random.nextInt(CommonUtil.MAX_ENEMY_PLANE);
        //如果隨機的數量是0 ,則一直循環,直到非0
        while(enemyPlaneCount == 0){
            enemyPlaneCount = random.nextInt(CommonUtil.MAX_ENEMY_PLANE);
        }
        return enemyPlaneCount;
        
    }

 

 

至此,在頁面展示出來之後,敵機也一些展示了出來。接下來我們要做的便是使敵機發射子彈。

在MainActivity.java中找到initBean方法,在方法中添加:如下代碼,作用就是把敵機的圖片set到surfaceView界面中

 

// 所有敵機
        surfaceView.setEnemyPlanes(enemyPlanes);
        
        surfaceView.setWindowHeight(windowHeight);
        surfaceView.setWindowWidth(windowWidth);

 
打開MySurfaceView.java類,在其中添加屬性: 爲其增加get  set 方法

 

// 敵機的圖片
    private List<ImageButton> enemyPlanes;

public List<ImageButton> getEnemyPlanes() {
        return enemyPlanes;
    }

    public void setEnemyPlanes(List<ImageButton> enemyPlanes) {
        this.enemyPlanes = enemyPlanes;
    }

 

在MySurfaceView.java 中的threadRun 方法中新增一個方法:enemyPlaneShot()如:

 

/**
     * 執行線程
     */
    private void threadRun() {

        // 你控制的飛機發射
        planeShot(yourPlane, false,null);
        Log.i(CommonUtil.VIEW_TAG, “控制的飛機射擊”);
        // 敵人的飛機開火
        enemyPlaneShot();
    }

 

 

 

 

 

增加enemyPlaneShot ()方法

 

/**
     * 敵人的戰機開始
     */
    private void enemyPlaneShot() {

        for (int i = 0,size = enemyPlanes.size(); i < size; i++) {

            EnemyPlane enemyPlane = new EnemyPlane();
            enemyPlane.setShot(true);
            enemyPlane.setLife(CommonUtil.ENEMY_PLAN_LIFE);
            // 敵機的位置隨機出現橫座標
            enemyPlane.setX(enemyPlanes.get(i).getX());
            enemyPlane.setY(enemyPlanes.get(i).getY());
            // 敵機圖片
            enemyPlane.setSrcPic(R.drawable.myplane);
            // 敵人的飛機發射  ,該方法原來不是這樣的,已經新增了參數
            planeShot(enemyPlane, true,enemyPlanes.get(i));
            
        }
    }

 

 

 

更改以後的planeShot 方法:

 

/**
     * 飛機發射
     *
     * @param plane
     * @param imageButton 敵機的圖片
     */
    private void planeShot(Plane plane, boolean isEnemyPlane, ImageButton enemyPlanImg) {
        // 控制飛機線程
        planeRunnable = new PlaneRunnable(context, holder);
        // 將控制的飛機綁定到該線程中
        planeRunnable.setPlane(plane);
        // 屏幕高度
        planeRunnable.setWindowHeight(windowHeight);
        planeRunnable.setWindowWidth(windowWidth);
        planeRunnable
                .setPlaneImg(getResources().getDrawable(plane.getSrcPic()));

        planeRunnable.setEnemyPlanes(enemyPlanImg);
        
        planeRunnable.setHandler(handler);
        // 是否爲敵機
        planeRunnable.setEnemyPlane(isEnemyPlane);
        shotThread = new Thread(planeRunnable);
        // 控制的飛機 開始射擊
        shotThread.start();
    }

 

 

到現在,PlaneRunnable 中也要增加其它的方法和變量,否則程序一直是報錯狀態

打開PlaneRunnable.java,在裏面加入新的屬性:

 

private boolean enemyPlane = false;// 是否爲敵機

    // 窗口的大小
    private int windowHeight;
    private int windowWidth;

    // 敵機的圖片
    private ImageButton enemyPlaneImg;
private Handler handler;

 

 

 

然後將run方法重新判斷,使敵機和你控制的飛機區分開來:

 

@Override
    public void run() {

        Canvas canvas = null;
        while (plane.isShot()) {

            canvas = holder.lockCanvas();
            canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);

            Paint paint = new Paint();
            paint.setColor(Color.BLUE);

            // 如果爲敵機,則這架飛機應該往下走,把敵機畫出
            if (isEnemyPlane()) {

                canvas.drawText(CommonUtil.BULLET, plane.getX()
                        + planeHalfWidth, plane.getY()+planeImg.getIntrinsicHeight(), paint);
                plane.setY(plane.getY() + 10);
                // 這裏這麼直接寫會報錯,線程非安全,原因是不能在子線程中直接更新UI
                // enemyPlaneImg.setY(plane.getY());
                Message msg = handler.obtainMessage();
                msg.arg1 = 1;
                msg.obj = enemyPlaneImg;
                msg.arg2 = (int) plane.getY();
                handler.sendMessage(msg);
            } else {
                canvas.drawText(CommonUtil.BULLET, plane.getX()
                        + planeHalfWidth, plane.getY(), paint);
            }

            holder.unlockCanvasAndPost(canvas);
            // 發射子彈
            shotOneBullet();

            // 如果敵機飛到了最下面,那該線程停止射擊
            if (plane.getY() >= windowHeight) {
                plane.setShot(false);
                break;
            }
             try {
             Thread.sleep(300);
             } catch (InterruptedException e) {
             e.printStackTrace();
             }
        }
        Log.i(CommonUtil.THREAD_TAG, “plane停止射擊”);
    }

 

 

 

 

在BulletRunnable.java中,也要增加相應的屬性:

 

  

 private boolean enemyBullet = false;

    // 窗口的大小
    private int windowHeight;
    private int windowWidth;

 

 

 

 

然後修改run方法,這樣做的目的只是爲了方便區分敵機和你控制的飛機,以及它們發射的子彈:

 

@Override
    public void run() {

        Canvas canvas = null;
        while (bullet.isFly()) {

            canvas = holder.lockCanvas();
            canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);

            Paint paint = new Paint();
            paint.setColor(Color.BLUE);
            // 判斷是敵機還是我方戰機
            if (!isEnemyBullet()) {
                // 我方戰機子彈往上走
                canvas.drawText(CommonUtil.BULLET, bullet.getX(),
                        bullet.getY() – 70, paint);
            } else {
                // 敵方戰機子彈往下走
                canvas.drawText(CommonUtil.BULLET, bullet.getX(),
                        bullet.getY() + 30, paint);
            }

            holder.unlockCanvasAndPost(canvas);

            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (!isEnemyBullet()) {
                bullet.setY(bullet.getY() – 70);
            } else {
                bullet.setY(bullet.getY() + 30);
            }
            if (bullet.getY() <= 0) {
                // 如果當前線程的Y超過了屏幕,則將該線程回收
                bullet.setFly(false);
                // 爆炸效果
                boom();
                break;
            }
            if (bullet.getY() >= windowHeight) {
                // 如果子彈的Y超過了屏幕底部,則將該線程回收
                bullet.setFly(false);
                break;
            }

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.i(CommonUtil.THREAD_TAG, “子彈飛行中”);
        }
        Log.i(CommonUtil.THREAD_TAG, “子彈線程結束”);
    }

 

 

到目前爲止,程序已經可以有敵機、你控制的飛機,所有的飛機都在發射子彈(只不過子彈碰到飛機之後,不會爆炸,而且敵機的移動不是很流暢,還有很多問題需要修改,下次遊戲代碼:《飛機大戰》安卓遊戲開發源碼(終)),現在效果圖如下:

 

本文章屬於原創性文章,珍惜他人勞動成果,轉載請註明出處: http://www.pm-road.com/index.php/2014/11/06/169/

 

飛機大戰遊戲源碼

飛機大戰遊戲源碼

 

飛機大戰遊戲源碼

飛機大戰遊戲源碼

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