1. 程式人生 > 其它 >SYSU-SSE 3D遊戲程式設計與設計 學習筆記(5)--物理系統與碰撞

SYSU-SSE 3D遊戲程式設計與設計 學習筆記(5)--物理系統與碰撞

簡易打飛碟--改進版

遊戲程式碼: 遊戲程式碼
遊戲演示視訊: 演示視訊

程式設計內容

改進之前的簡易打飛碟遊戲-- 先前部落格

  1. adapter 模式設計圖修改飛碟遊戲
  2. 使它同時支援物理運動與運動學(變換)運動

實現思路

  • roundController增加一個 publicbool 型別的變數 ifPhysicManager 來表示是否使用物理運動
  • 增加一個物理運動的動作類 PhysicalAction ,繼承 SSAction
  • 增加一個物理運動的管理類 PhysicalActionManager ,繼承 SSActionManager
  • 改進飛碟資訊類 UFOInfo ,增加對不同運動型別飛碟的支援

改進程式碼

  • roundController
if(ifPhysicManager)
    this.gameObject.AddComponent<PhysicalActionManager>();
else
    this.gameObject.AddComponent<SSActionManager>();

通過判斷不同的運動實現使用不同的動作管理

UFOInfo ufoInfo = ufofactory.getUFO(level, ifPhysicManager);
if(ifPhysicManager){
    PhysicalAction ac = PhysicalAction.getUFOAction(ufoInfo, level);
    actionManager.RunAction(ufoInfo.ufo, ac, null);
}
else {
    UFOAction ac = UFOAction.getUFOAction(ufoInfo, level);
    actionManager.RunAction(ufoInfo.ufo, ac, null);
}

通過判斷不同的運動使用不同的飛碟(是否使用剛體)並呼叫不同的動作管理類

  • PhysicalAction
Rigidbody rigidBody = action.ufo.ufo.GetComponent<Rigidbody>();
rigidBody.velocity = action.aim * action.speed;
rigidBody.useGravity = false;
return action;

當獲取飛碟動作時,將飛碟的剛體元件賦予速度

public void FixedUpdate()
{
    if(hasPaused) {         //若之前暫停遊戲,則需將速度重置
        Rigidbody rigidBody = ufo.ufo.GetComponent<Rigidbody>();
        rigidBody.velocity = aim * speed;
        hasPaused = false;
    }
    time += Time.fixedDeltaTime;        //以時間度量飛碟出現時間
    if(time > 2) {
        time = 0;
        this.destroy = true;
        this.enable = false;
        Singleton<UFOFactory>.Instance.freeUFO(ufo);
        ufo.ufo.SetActive(false);
    }
}

public void Pause()
{
    hasPaused = true;
    Rigidbody rigidBody = ufo.ufo.GetComponent<Rigidbody>();
    rigidBody.velocity = Vector3.zero;
}

因為在運動學實現的遊戲,暫停遊戲時動作類停止 Update 此時飛碟不再運動;而物理學實現的遊戲中,需將飛碟速度調整至0,所以增加 Pause 方法

  • PhysicalActionManager
if(roundCtrl.status == "pause") {
    foreach (KeyValuePair<int, SSAction> kv in actions) {
        PhysicalAction ac = (PhysicalAction)kv.Value;
        ac.Pause();
    }
    return;
}

由之前所述,Pause 方法由動作管理類來呼叫

  • UFOInfo
if(ifPhysicManager) ufo.AddComponent<Rigidbody>();

UFOInfo通過 roundController 的引數來判斷是否要新增剛體元件

因視訊與動圖與先前幾乎無差別,在此不重複演示
最後感謝參考部落格