1.介紹
遊戲開發時還是蠻經常會遇到與時間有關的功能,最近整理了下把遊戲線上的倒數計時抽出了一個介面。
線上遊戲的倒數計時通用需求一般有:
1).倒數計時的時間,比如樹的重生長時間為3分鐘,角色死亡復活倒數計時需要30秒..
2).可以暫停的功能,比如單機遊戲點開設定,那麼樹的重生長倒數計時應該停止;也可以不使用暫停功能,但要提供暫停功能..
3).提供倒數計時生命週期的監聽回撥功能,提供在倒數計時開始時、倒數計時暫停時、倒數計時完成時的監聽介面。
開始時的監聽大多與事件的結果有關,規範性還是寫上,比如在樹被砍倒,呼叫動畫和道具邏輯,然後啟動重生長倒數計時,開始監聽呼叫倒數計時UI滑鼠懸停在樹時顯示,遊戲暫停時呼叫重生長的UI、邏輯、動畫等暫停,倒數計時結束時,樹重新到原樣,同時關閉倒數計時。
2.實現
整體使用一個表裡二層的結構來實現上面需求,其中需要一個實現倒數計時功能的裡層類DownClock,將功能及資料封裝在這個類中,提供一些操控介面給表層類TimeMgr,TimeMgr將管理所有的DownClock,併為外部功能模組提供介面。
DownClock類的實現:
點選檢視程式碼
public class DownClock
{
bool isPause = false;
bool isOver = false;
float timer;
//各個監聽
Action OnStart;
Action OnPause;
Action OnResume;
Action OnComplete;
public DownClock(float _timer, Action _OnComplete = null)
{
timer = _timer;
OnComplete = _OnComplete;
}
public DownClock(float _timer, Action _OnStart = null, Action _OnPause = null, Action _OnResume = null, Action _OnComplete = null)
{
timer = _timer;
OnStart = _OnStart;
OnPause = _OnPause;
OnResume = _OnResume;
OnComplete = _OnComplete;
OnStart?.Invoke();
}
//依託於TimeMgr的mono update
public void TimeDown(float delta)
{
if (isOver || isPause) return;
timer -= delta;
if (timer < 0)
{
timer = 0f;
isPause = true;
isOver = true;
OnComplete?.Invoke();
}
}
//一些對外功能介面
public bool GetIsOver()
{
return isOver;
}
public float GetTimer()
{
return timer;
}
public void AddTime(float value)
{
timer += value;
}
public void ResumeClock()
{
isPause = false;
OnResume?.Invoke();
}
public void PauseClock()
{
isPause = true;
OnPause?.Invoke();
}
}
TimeMgr類的部分實現:
點選檢視程式碼
public partial class TimeMgr : Singleton<TimeMgr>
{
void Awake()
{
base.Awake();
DontDestroyOnLoad(gameObject);
}
void Update()
{
UpdateDownClocks();
}
//這裡用List寫了個簡單的管理與對外介面
public List<DownClock> down_clocks = new List<DownClock>();
public void UpdateDownClocks()
{
if (down_clocks.Count == 0) return;
//遍歷所有鍾,結束的刪除,其餘的傳入delta time倒數計時
for (int i = 0; i < down_clocks.Count; i++)
{
DownClock clock = down_clocks[i];
if (clock.GetIsOver())
{
down_clocks.Remove(clock);
continue;
}
clock.TimeDown(Time.deltaTime);
}
}
public void AddDownClock(float timer, Action _OnComplete = null)
{
DownClock clock = new DownClock(timer, _OnComplete);
down_clocks.Add(clock);
}
public void AddDownClock(float timer, Action _OnStart = null, Action _OnPause = null, Action _OnResume = null, Action _OnComplete = null)
{
DownClock clock = new DownClock(timer,_OnStart,_OnPause,_OnResume,_OnComplete);
down_clocks.Add(clock);
}
}