Android_手把手教你寫跳躍類遊戲(2)

這是第二篇博客,在本次教程中,我們將完成小球這個類的編寫

首先給大傢看下小球這個類的類圖:

 

 

主要確定小球的坐標:x,y。小球的半徑:r。以及小球的運動函數和如何講小球畫在屏幕上的draw()函數。

難點是:move()函數。我們將簡單的模擬一個物理環境,使小球看上去顯得很有彈性。具體關於這部分,我會在接下去的文章中進行解答。

下面給出Ball.java的代碼

[java] package jumpball.game; 
 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
 
public class Ball { 
    float r, x, y; 
    private Paint mPaint; 
    // 最大垂直速度 方向向上 -16.  
    float MAXVERTICALSPEED = -16, MAXVERTICALA = 1; 
    // 默認最大高度  
    float defaultJumpHight; 
    // 小球在垂直方向上需要移動的距離!  
    float verticalMove; 
    float ha = 0, va = 1f, v0v, vtv, v0h, vth; 
    GameView gameView; 
 
    public Ball(GameView gameView) { 
        this.gameView = gameView; 
        mPaint = new Paint(); 
        mPaint.setColor(Color.BLACK); 
        defaultJumpHight = gameView.height / 3; 
        r = gameView.width / 36; 
        y = gameView.height – r * 2; 
        x = gameView.width / 2 – r; 
        //根據加速度公式計算得出Vt^2-V0^2=2AX  
        MAXVERTICALSPEED = -(int) ((float) Math.sqrt(2 * gameView.height / 3) – 1); 
        verticalMove = defaultJumpHight; 
        v0v = MAXVERTICALSPEED; 
    } 
 
    public void draw(Canvas canvas) { 
        move(); 
        canvas.drawCircle(x, y, r, mPaint); 
    } 
 
    public void move() { 
        // Vt=V0+aT 當前速度=初始速度+加速度*時間  
        vtv = v0v + va; 
        // 當下降速度達到一定程度時,設置加速度為0.4f。  
        if (vtv > -5 * MAXVERTICALSPEED / 8) { 
            va = 0.4f; 
        } else { 
            va = MAXVERTICALA; 
        } 
        // 當當前還需上升的高度 大於默認高度時,速度繼續保持最大速度,vtv<0表示方向向上  
        if (verticalMove > defaultJumpHight && vtv < 0) { 
            vtv = MAXVERTICALSPEED; 
        } 
        float vMove = (v0v + vtv) / 2; // 這一次垂直高度移動距離。  
        verticalMove = verticalMove + vMove;// 減小時,表示網上移動瞭  
        y = y + vMove; 
        v0v = vtv; 
        if (y > gameView.height) {// 觸地瞭  
            y = gameView.height – this.r; 
            v0v = MAXVERTICALSPEED; 
            verticalMove = defaultJumpHight; 
        } 
    } 

package jumpball.game;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

public class Ball {
 float r, x, y;
 private Paint mPaint;
 // 最大垂直速度 方向向上 -16.
 float MAXVERTICALSPEED = -16, MAXVERTICALA = 1;
 // 默認最大高度
 float defaultJumpHight;
 // 小球在垂直方向上需要移動的距離!
 float verticalMove;
 float ha = 0, va = 1f, v0v, vtv, v0h, vth;
 GameView gameView;

 public Ball(GameView gameView) {
  this.gameView = gameView;
  mPaint = new Paint();
  mPaint.setColor(Color.BLACK);
  defaultJumpHight = gameView.height / 3;
  r = gameView.width / 36;
  y = gameView.height – r * 2;
  x = gameView.width / 2 – r;
  //根據加速度公式計算得出Vt^2-V0^2=2AX
  MAXVERTICALSPEED = -(int) ((float) Math.sqrt(2 * gameView.height / 3) – 1);
  verticalMove = defaultJumpHight;
  v0v = MAXVERTICALSPEED;
 }

 public void draw(Canvas canvas) {
  move();
  canvas.drawCircle(x, y, r, mPaint);
 }

 public void move() {
  // Vt=V0+aT 當前速度=初始速度+加速度*時間
  vtv = v0v + va;
  // 當下降速度達到一定程度時,設置加速度為0.4f。
  if (vtv > -5 * MAXVERTICALSPEED / 8) {
   va = 0.4f;
  } else {
   va = MAXVERTICALA;
  }
  // 當當前還需上升的高度 大於默認高度時,速度繼續保持最大速度,vtv<0表示方向向上
  if (verticalMove > defaultJumpHight && vtv < 0) {
   vtv = MAXVERTICALSPEED;
  }
  float vMove = (v0v + vtv) / 2; // 這一次垂直高度移動距離。
  verticalMove = verticalMove + vMove;// 減小時,表示網上移動瞭
  y = y + vMove;
  v0v = vtv;
  if (y > gameView.height) {// 觸地瞭
   y = gameView.height – this.r;
   v0v = MAXVERTICALSPEED;
   verticalMove = defaultJumpHight;
  }
 }
}
 
在GameVIew類裡面定義一個小球對象。

[java] Ball ball; 
Ball ball;
在GameView的構造方法裡面進行實例化

[html] ball=new Ball(this); 
ball=new Ball(this);
同時在GameView的mDraw函數裡面添加

[html] ball.draw(mCanvas); 
ball.draw(mCanvas);
這樣我們就完成瞭ball對象…娃哈哈~(遊戲 已經有點樣子瞭!)

運行程序。我們就能看到一個有彈性的小球瞭,在那邊跳啊跳~~~~

 

最後我們完成小球的左右移動。這部分比較簡單~~~

在GameView定義兩個boolean變量表示左右鍵是否按下

同時重寫兩個方法

[html] public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_BACK) { 
        gameActivity.finish(); 
        return true; 
    } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { 
        leftKeyDown = true; 
    } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { 
         rightKeyDown = true; 
    } 
    return true; 

public boolean onKeyUp(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { 
         leftKeyDown = false; 
    } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { 
         rightKeyDown = false; 
    } 
    return true; 

 public boolean onKeyDown(int keyCode, KeyEvent event) {
  if (keyCode == KeyEvent.KEYCODE_BACK) {
   gameActivity.finish();
   return true;
  } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
   leftKeyDown = true;
  } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
    rightKeyDown = true;
  }
  return true;
 }
 public boolean onKeyUp(int keyCode, KeyEvent event) {
  if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
    leftKeyDown = false;
  } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
    rightKeyDown = false;
  }
  return true;
 }
然後在小球的move方法裡面添加:

[html] //水平移動設置 
        if(gameView.leftKeyDown==true){ 
            xx=x-10; 
        } 
        if(gameView.rightKeyDown==true){ 
            xx=x+10;              
        } 
        if (x < r) { 
            x = r; 
        } 
        if (x > gameView.width – r) { 
            x = gameView.width – r; 
        } 
//水平移動設置
  if(gameView.leftKeyDown==true){
   x=x-10;
  }
  if(gameView.rightKeyDown==true){
   x=x+10;    
  }
  if (x < r) {
   x = r;
  }
  if (x > gameView.width – r) {
   x = gameView.width – r;
  }
本來寫到這裡就已經完成瞭小球的左右移動,但是實際運行卻發現根本移動不瞭~~~

我查瞭下資料發現問題在這:

我們自己定義的View,必須獲得焦點之後才會調用onKeyDown方法~而Activty的onKeyDown方法是當所有空控件均沒處理的時候才會被調用。

所以我們在GameView的構成方法裡面添加一句:

[html] setFocusable(true); 
setFocusable(true);
好瞭。。。大功告成~~~~這樣我們就可以控制小球的移動瞭!!!

關於小球move函數,我會在視頻中詳細的講解~~~

下面貼出程序的運行效果圖:                             以及項目的一個結構:

 

 

源碼下載地址請看最終版!

 

摘自 EaSy的專欄

發佈留言