定義
將各種命令操作設計成類進行保存,使用時調用類的對象來實現操作。
優點:
- 操作設計成類後,相比於將操作封裝成函數,在引起執行操作的條件不變時想要改變操作內容就不需要更改函數源代碼,只需要獲取新操作的對象。(例如遊戲中K鍵代表攻擊,當人物武器不同時,執行攻擊時的動作不同。當需要獲得新武器時,不需要更改函數代碼去改變攻擊動作,只需要設計新的攻擊動作類,返回給人物調用即可)
- 容易實現撤銷(UNDO)和重做(REDO)操作
- 實現了遊戲物體與操作之間的解耦,增強了靈活性(遊戲AI可以通過加入一系列操作或者刪除一系列操作來控制遊戲難度)
例子(基於U3D實現)
WSAD控制遊戲物體前後左右行動
Z鍵撤銷操作 R鍵重做操作
- Commands類(抽象命令類)
public abstract class Commands {
/// <summary>
/// 執行命令函數
/// </summary>
/// <param name="actor">執行命令的遊戲對象</param>
public virtual void Execute(GameObject actor) { }
/// <summary>
/// 撤銷命令函數
/// </summary>
/// <param name="actor"></param>
public virtual void UnDo(GameObject actor) { }
}
- WalkForward&&WalkBack(具體命令類)
public class WalkForward : Commands {
private Vector3 before;
public override void Execute(GameObject actor)
{
//記錄當前位置用於實現撤銷操作
before = actor.transform.localPosition;
//將操作的遊戲物體向前移動一個單位
actor.transform.SetPositionAndRotation(Vector3.forward + before,Quaternion.identity);
}
public override void UnDo(GameObject actor)
{
//將操作的遊戲物體恢復爲原位置
actor.transform.SetPositionAndRotation(before, Quaternion.identity);
}
}
public class WalkBack : Commands {
private Vector3 before;
public override void Execute(GameObject actor)
{
//記錄當前位置用於實現撤銷操作
before = actor.transform.localPosition;
//將操作的遊戲物體向後移動一個單位
actor.transform.SetPositionAndRotation(Vector3.back + before,Quaternion.identity);
}
public override void UnDo(GameObject actor)
{
//將操作的遊戲物體恢復爲原位置
actor.transform.SetPositionAndRotation(before, Quaternion.identity);
}
}
- InputHandler(響應鍵盤事件返回相應的命令對象)
public class InputHandler : MonoBehaviour {
//前進命令對象
public Commands command_F;
//後退命令對象
public Commands command_B ;
//根據相應事件返回相應的命令對象
public Commands Handler()
{
if (Input.GetKeyDown(KeyCode.W))
return command_F = new WalkForward();
if (Input.GetKeyDown(KeyCode.S))
return command_B = new WalkBack();
return null;
}
}
- Control(控制類)
public class Control : MonoBehaviour {
public GameObject player; //執行命令的遊戲物體
private InputHandler input;
private Commands command; //當前執行的命令
private Commands PreCommand; //撤銷操作命令
//命令隊列保存已執行的命令 實現撤銷多步操作
private LinkedList<Commands> list;
// Use this for initialization
void Start () {
list = new LinkedList<Commands>();
input = gameObject.GetComponent<InputHandler>();
}
// Update is called once per frame
void Update () {
ControlPlayer();
}
public void ControlPlayer()
{
command = input.Handler();
if(command!=null)
{
command.Execute(player);
//命令隊列大小爲4
//未滿時加入隊尾 已滿時移除隊首加入隊尾
if(list.Count==4)
{
list.RemoveFirst();
list.AddLast(command);
}
else
{
list.AddLast(command);
}
}
//按鍵Z實現撤銷操作
if (Input.GetKeyDown(KeyCode.Z))
{
if (list.Count!=0)
{
PreCommand = list.Last.Value;
list.RemoveLast();
PreCommand.UnDo(player);
}
}
}
}