作者NDark (溺於黑暗)
看板GameDesign
标题Re: [心得] 容易被遗忘的游戏设计模组(1)
时间Sat Nov 6 18:37:05 2010
※ 引述《NDark (溺於黑暗)》之铭言:
: 实务面是,
: 在游戏层的各个元件(不管是绘图,移动,动画)都要能取得目前FPS的资讯,
: 或是当此元件的机制需要这个资讯的时候,必须要从最外层一路传进去。
最近在做一些基底类别,有一个地方还没决定.
可以拿出来跟各位讨论一下.不知道有没有我想不周到的地方.
问题如下
游戏中的物件(Object,或Entity元件)散落在游戏中的各个角落.
不管用什麽方式把它们串起来,都会有执行的Process.
而这些流程可能就会用到FPS的资讯.
或是这个流程想要知道 "距离上次执行.经过了多少时间?"
目前我这里考量的有几种作法,先列出来给各位参考.
A. FPS一路传入式
每个画格.每个Process都一定要跑到.
然後强迫传入此画格经过多少时间(Elapsed Time).
因此实作上就是所有物件基底的类别会有这个成员函式,
所有继承的类别物件都强迫实作它.如下:
virtual GameObject::Main( double _ElapsedTimeSec ) ;
优点: 一条鞭式,撰写简单.
缺点: 所有物件都被无可避免的强迫串上一个管理器,
所有物件也被强迫一定要用这样的方式撰写.比较没有弹性.
对於那些物件之中的小物件,或是不希望每个画格都执行到的流程.
就必须要特别考量两次执行到底累积了多久时间.
B. 独立的计时器
考量到每个物件不一定每个画格都要跑到,某些物件譬如说log记录器,每1秒才跑一次.
每个Process有自己的计时器.跑起来的时候自动会计算与上次差了多久.
实作方式就是有一个Timer物件,会去参照系统时间.
AnyObj.MyProcess()
{
ElapsedTimeSec = TimerObj.getElapsedSec() ;
TimerObj.Restart() ;
...
优点: 每个物件只要自己去取得过了多久就好.不用串上统一的管理器.作法弹性.
也不用每个画格都执行.
缺点: 因为是取得系统时间来计算跟上次差了多久.
所以游戏没办法控制这个时间差.
C. 注册FPS通知器
A与B的混合型.每个会用到FPS的物件.
都去跟一个唯一(singleton)的FPS管理器来注册自己.
因此这个管理器就就像是有一堆闹钟.
每个画格就对这些闹钟累加一次.
每个物件不定时间执行的时候.就去取得自己的闹钟.取得经过时间.然後重置闹钟.
实作如下
AnyObj::AnyObj()
{
TimerHandleID = singletonFPSManager().RegisterTimer( this ) ;
...
AnyObj.Run()
{
ElapsedTime = singletonFPSManager().getElapsedTime( TimerHandleID ) ;
singletonFPSManager().resetTimer( TimerHandleID ) ;
...
优点: 物件不用串上管理器.作法弹性.
缺点: 物件必须记得要去注册自己.取得handle id.且保证这个id不会重复.
D. 独立的装饰型计时器
B的变化型.在取得系统时间前.再包装一层放大器.
这样就可以让游戏管理器自由调整给每个物件的时间经过
装饰型计时器实作如下
class DecorateTimer : public SysTimer
{
double AmplifyValue = ...
优点: 物件改跟装饰型计时器要资料.
不用串上管理器.作法弹性.
还可以依照不同的物件类型取得放大或原始的经过时间
缺点: 使用时要记得现在是用装饰过後的Timer.
使用上必须明了自己在取得的时间是什麽意义.
以及.要避免有程式设计员不知道有这个装饰计时器.
还傻傻的跑去拿系统时间.以至於物件之间不同步的情况.
--
"May the Balance be with U"(愿平衡与你同在)
视窗介面游戏设计教学,讨论,分享。欢迎来信。
视窗程式设计(Windows CLR Form)游戏架构设计(Game Application Framework)
游戏工具设计(Game App. Tool Design )
电脑图学架构及研究(Computer Graphics)
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 118.167.132.126
※ 编辑: NDark 来自: 118.167.132.126 (11/06 18:39)