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);
}
}