《杜增強講Unity之Tanks坦克大戰》11-游戲流程控制


11 游戲流程控制

使用協程來控制游戲流程

11.1 添加MessageText

首先添加一個Text來顯示文字

 
image

設置GameMgr

 
image

11.2 游戲整體流程

 

下面GameMgr.cs最終代碼預覽,后面我們逐個講解.

using UnityEngine;

using UnityEngine.UI;

using System.Collections;

public class GameMgr : MonoBehaviour

{

private int roundNumber = 0; // 輪次. public Text messageText; // ui text private bool gameOver = false; // 本輪游戲是否已結束 // Use this for initialization void Start () { StartCoroutine ( GameLoop ()); } private IEnumerator GameLoop () // 游戲主循環邏輯 { yield return StartCoroutine (RoundStart ()); // 開始本輪游戲. yield return StartCoroutine (RoundPlay ()); // 游戲進行中. yield return StartCoroutine (RoundEnd ()); // 本輪游戲結束. StartCoroutine (GameLoop ()); // 開始下一輪游戲 } private IEnumerator RoundStart () { roundNumber++; // 累計輪數 messageText.text = "ROUND " + roundNumber; yield return new WaitForSeconds (2f);// 等待2s繼續 } private IEnumerator RoundPlay () { messageText.text = string.Empty; // 清空 "GamePlaying";// while (!gameOver) // 游戲結束才跳出 { yield return null; } } private IEnumerator RoundEnd () { string message = "GameEnd"; // 顯示分數 messageText.text = message; yield return new WaitForSeconds (2f);// 等待2s繼續 } 

}

11.3 開始本輪游戲 RoundStart()

開始新一輪游戲是需要做三件事情

ResetTanks (); // 重置坦克

DisableTanksControl (); // 禁用坦克操作

camera.SetStartPositionAndSize ();// 重置相機

為了方便對坦克進行操作,我們寫了TankMgr來實現對於坦克的控制。

 
image

TankMgr.cs

using UnityEngine;

using System.Collections;

public class TankMgr : MonoBehaviour {

public Transform spawnPoint; // 出生點 public void Reset(){// 重置坦克 transform.position = spawnPoint.position;//坐標 transform.rotation = spawnPoint.rotation;//旋轉角度 GetComponent<Health> ().blood = 100;//血值 } public void EnableControl(){// 啟用控制 GetComponent<TankMove> ().enabled = true; GetComponent<TankShoot> ().enabled = true; } public void DisableControl(){ // 禁用控制 GetComponent<TankMove> ().enabled = false; GetComponent<TankShoot> ().enabled = false; } 

}

還需要設置兩個GameObject作為SpawnPosition

 
image
 
image

TankMgr是直接掛載到Tank上面的

 
image

最終RoundStart()函數里面是這樣的

private IEnumerator RoundStart ()// 開始本輪游戲.

{

    ResetTanks (); // 重置坦克 DisableTanksControl (); // 禁用坦克操作 

camera.SetStartPositionAndSize ();// 重置相機

    roundNumber++; // 累計輪數 messageText.text = "ROUND " + roundNumber; yield return new WaitForSeconds (2f);// 等待2s繼續 } 

因為要控制所有坦克,所以需要一個數組保存所有坦克。

public TankMgr[] tanks; // 所有坦克

private void ResetTanks(){ // 重置坦克狀態

foreach( TankMgr tm in tanks) tm.Reset(); 

}

private void DisableTanksControl(){ // 禁用坦克操作

foreach( TankMgr tm in tanks) tm.DisableControl(); 

}

然后當游戲開始的時候重新起來坦克控制

IEnumerator RoundPlay(){

    foreach( TankMgr t in tanks){ t.EnableControls (); } messageText.text = "Playing"; while( true ){// 一直運行,直到有一個坦克掛掉 yield return null; } } 

這是游戲處理運行過程,我們需要判斷什么時候有坦克已經掛掉.

這時候我們發現按照之前在Health.cs里面的處理,坦克是直接被Destroy掉的.所以這個地方我們做一些調整.當坦克掛掉之后,我們把它SetActive(false)

public void TakeDamage( float damage){

    currentBlood -= damage; // 掉血 slider.value = currentBlood; // 更新血槽顯示 if (currentBlood <= 0) { // die //ps.transform.parent = null; ps.Play (); audioSource.clip = explosionAudio; audioSource.Play (); //Destroy (ps.gameObject, ps.duration); //Destroy (gameObject); gameObject.SetActive ( false ); } } 

這樣當坦克掛掉之后並不是真的把它銷毀了,我們可以使用gameObject.activeSelf來判斷坦克是否已經掛掉

bool OneTankLeft(){ // 判斷是否有坦克掛掉

    foreach( TankMgr t in tanks){ if (t.gameObject.activeSelf == false) return true; } return false; } 

這樣我們就可以終止RoundPlay里面的while語句了

IEnumerator RoundPlay(){

    foreach( TankMgr t in tanks){ t.EnableControls (); // 啟用坦克控制 } messageText.text = ""; while( !OneTankLeft() ){// 一直運行,直到有一個坦克掛掉 yield return null; } } 

這樣程序就可以執行到下一個階段,就是RoundEnd函數里面了.

在游戲結束的時候我們需要知道玩家到底是誰,所以我們什么一個winner來保持贏家

private int winner; // 贏家

int GetWinner(){ // 誰是贏家

    for(int i=0;i<tanks.Length;i++){ if (tanks [i].gameObject.activeSelf == true) return i; } return 0; } 

這個方法在如果有一個坦克掛掉的時候就返回此坦克在Tanks數組中的索引.如果兩個坦克都掛掉了(是有這種可能的),現在返回的仍然是0,可以返回一個-1,單獨處理,這個我們在這就不講了,大家下去自己實現一些.

IEnumerator RoundEnd(){ // 本輪游戲結束

    winner = GetWinner ();

    messageText.text = "Player "+(winner+1)+" wins!";// 顯示贏家 yield return new WaitForSeconds (2f); } 

這樣游戲就可以一輪一輪的進行下去了,如果我們想在某一輪后結束游戲,可以判斷roundNum來實現.

 

---------------------------我是目錄分割線---------------------------

《杜增強講Unity之Tanks坦克大戰》1-准備工作

《杜增強講Unity之Tanks坦克大戰》2-場景設置

《杜增強講Unity之Tanks坦克大戰》3-添加坦克

《杜增強講Unity之Tanks坦克大戰》4-坦克的移動和旋轉

《杜增強講Unity之Tanks坦克大戰》5-子彈

《杜增強講Unity之Tanks坦克大戰》6-發射子彈

《杜增強講Unity之Tanks坦克大戰》7-坦克血條

《杜增強講Unity之Tanks坦克大戰》8-子彈碰撞處理

《杜增強講Unity之Tanks坦克大戰》9-發射子彈時蓄力

《杜增強講Unity之Tanks坦克大戰》10-相機控制

《杜增強講Unity之Tanks坦克大戰》11-游戲流程控制

---------------------------我是目錄分割線---------------------------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM