遊戲中的設計模式一(單例模式與狀態模式)

這系列文章博主將介紹給大家遊戲中常用的設計模式

文章並不是純粹的講一大堆理論抽象的內容,重點也不再這裏。

其實設計模式如果大家編寫閱讀的代碼量多的話,自然而然的自己有意思地使用到了。

只是沒有這麼那種系統的意識,所以這系列文章通過一個Unity3d遊戲實例讓大家感受什麼設計模式,設計模式的作用。

本文介紹給大家的單例模式以及狀態模式

寫在前面

在遊戲角色的各個戰鬥狀態(idle,attack,run......)、場景狀態(開始場景、戰鬥場景、主城場景.....)都可以使用設計模式來管理組織

本文通過一個實例介紹使用狀態模式來創建管理遊戲中的多個遊戲場景

本文主要目的是介紹設計模式,所以一些unity基礎內容我就不介紹給大家,大家可以參考源碼學習點擊打開鏈接

案例介紹

在遊戲開始場景有兩個按鈕,點擊一個按鈕進入戰鬥場景,點擊另外一個按鈕進入主城場景

案例雖簡單,但是已經滿足我們本文的目標

編寫代碼

創建一個場景狀態基類

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ISceneState
{
	protected string mSceneName { get; set; }

	public ISceneState(string scennName)
	{
		this.mSceneName = scennName;
	}

	public virtual void StartScene() { }
	public virtual void UpadteScene() { }
	public virtual void EndScene() { }
}


接下來介紹使用一個對象來管理各個場景

其中使用單例模式,可以理解爲實例一個管理者,由這個管理者來切換我們的目標場景

設計成單例模式的作用的話方便我們統一管理,增強代碼靈活性調用簡單,避免不必要的內存消耗等

using System;
using System.Collections.Generic;
using System.Text;

class SceneStateManager
{
	//單例模式
	private static SceneStateManager _instance;
	public static SceneStateManager GetInstacne
	{
		get
		{
			if (_instance == null)
			{
				_instance = new SceneStateManager();
			}

			return _instance;
		}
	}

	private ISceneState mState { get; set; }

	public void SetSceneState(ISceneState state)
	{
		//對上一個場景狀態退出處理
		if (mState != null)
		{
			mState.EndScene();
		}
		mState = state;
		//對新場景狀態進行開始處理
		if (mState != null)
		{
			mState.StartScene();
		}
	}


	public void UpdateSceneState()
	{
		if (mState != null)
		{
			mState.UpadteScene();
		}
	}
}


接下來就是創建各個場景類了,場景類都基礎自ISceneState類

開始場景類StartSceneState

using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.UI;

class StartSceneState : ISceneState
{
	public StartSceneState() : base("StartScene") { }

	public override void StartScene()
	{
		GameObject.FindGameObjectWithTag("Battle").GetComponent<Button>().onClick.AddListener(OnBtnBattle);
		GameObject.FindGameObjectWithTag("MainMenu").GetComponent<Button>().onClick.AddListener(OnBtnMainMenu);
	}

	private void OnBtnBattle()
	{
		SceneStateManager.GetInstacne.SetSceneState(new BattleScene());
	}


	private void OnBtnMainMenu()
	{
		SceneStateManager.GetInstacne.SetSceneState(new MainMenuSceneState());
	}
}


戰鬥場景類BattleScene

using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine.SceneManagement;

class BattleScene : ISceneState
{
	public BattleScene() : base("BattleScene")
	{
	}

	public override void StartScene()
	{
		SceneManager.LoadScene(this.mSceneName);
	}
}


主城場景類MainMenuSceneState

using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine.SceneManagement;

class MainMenuSceneState : ISceneState
{
	public MainMenuSceneState() : base("MainMenuScene")
	{
	}

	public override void StartScene()
	{
		SceneManager.LoadScene(this.mSceneName);
	}
}


好了各個場景都已經實現好了

接下來是創建一個類用於調用管理類(SceneStateManager),其繼承自Monobehavior,將其掛載到一個遊戲對象上

代碼如下

using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;

class GameContext : MonoBehaviour
{
	private void Start()
	{
		SceneStateManager.GetInstacne.SetSceneState(new StartSceneState());
	}

	private void Update()
	{
		SceneStateManager.GetInstacne.UpdateSceneState();
	}
}


內容總結

創建一個單例管理類,用於管理場景之間的切換,每個場景都擁有自己的一個狀態類來處理本場景狀態中的邏輯時間


如果你喜歡本文方式來介紹遊戲中的設計模式,那麼可以關注blog.liujunliang.com.cn更多內容持續更新



發佈了120 篇原創文章 · 獲贊 181 · 訪問量 41萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章