bada 2D
遊戲編程之五——一個基於定時器的遊戲循環
在上篇《
bada 2D
遊戲編程之四——設計遊戲循環》中對比較常見的幾種設計遊戲循環的理論知識進行了闡述,下面按照
bada
平臺的編程知識來實現一種遊戲循環。實現「時間驅動」的
遊戲循環一般採用
2
種方式,一種是基於定時器的遊戲循環,還有一種是基於線程的遊戲循環。在本篇文章中給你們介紹如何在
bada
平臺上實現一個基於定時器的遊戲循環。
1
,定時器使用方法
bada
平臺提供了
Osp::Base::Runtime::Timer
來做爲系統的定時器,這是
Timer
的主要函數:
函數
|
功能描述
|
Construct(const ITimerEventListener& listener)
|
初始化函數,傳入監聽器
|
Start(int timeout)
|
開始計時
|
Cancel(void)
|
取消計時
|
同時還有一個
Osp::Base::Runtime::ITimerEventListener
接口類來配合它一塊兒使用,
ITimerEventListener
類的主要函數:
函數
|
功能描述
|
OnTimerExpired(Timer& timer)
|
定時器到時時被回調到
|
這樣當
Timer
設定的時間到達後,
ITimerEventListener
中的事件處理函數
OnTimerExpired(Timer& timer)
就會被回調到,在這裏面進行事件處理就能夠了。
2
,實現的思路
實現的思路主要是將遊戲的循環和遊戲
(
事件處理、邏輯更新、渲染繪製
)
進行分離,從而能夠將遊戲循環模塊和遊戲模塊分離開來,下降相互之間的依賴程度。經過加入一個接口類將
HandleEvent(),UpdateLogic()
和
Draw()
封裝起來,而後在遊戲循環中調用這個接口類的函數來通知遊戲模塊進行處理,從而實現了相互之間的獨立。
在寫這個博客系列的過程當中,但願可以實現一個簡單的遊戲引擎,並將這個遊戲引擎的縮寫定爲
TG
,一是表示爲二維遊戲
(Two-Dimensional Game)
的意思,再是如今網上有傳言要將
bada
和
Tizen
進行合併,到時這個基於
bada
的遊戲引擎應該是能夠運行在
Tizen
上的,因此也能夠表示爲
Tizen Game
的縮寫。這樣設計的屬於遊戲引擎的類都會加入
TG
作爲標識。
3
,類圖
下圖是對遊戲循環涉及到的各種之間的關係。
4
,相關的類和接口
下面對實現遊戲循環的一些基本的接口和類進行介紹:
(
1
)
ITGStateListener
類,
I
表示是一個接口類
(Interface)
。這個類封裝了遊戲的三種狀態,分別是處理事件、更新邏輯和渲染繪製。遊戲模塊只須要實現這個接口,進行註冊後就能夠接到來自遊戲循環的通知,在各個處理函數中進行相應的處理就能夠了,從而驅動遊戲運行。
class
ITGStateListener
{
public
:
virtual
~ITGStateListener(){};
virtual
void
HandleEvent() = 0;
virtual
void
UpdateLogic(
int
frameInterval) = 0;
virtual
void
Draw() = 0;
};
(
2
)
TGLoopBase
類,這是遊戲循環的基類,實現各類遊戲循環均可以經過繼承這個類來實現循環,它封裝了遊戲循環的一些基本方法和成員。這個類包含一些純虛函數,因此是不能被實例化的。
class
TGLoopBase
{
public
:
TGLoopBase();
virtual
~TGLoopBase();
virtual
result
Construct(
void
) = 0;
public
:
virtual
void
SetFrameInterval(
int
interval);
virtual
void
SetStateListener(
ITGStateListener
* pListener);
virtual
void
Start() = 0;
virtual
void
Pause() = 0;
virtual
void
Stop() = 0;
protected
:
int
__frameInterval
;
ITGStateListener
*
__pStatusListener
;
};
(
3
)
TGTimerLoop
類,這是遊戲循環對應的一個具體的類,它繼承了
TGLoopBase
,並使用
Osp::Base::Runtime::
Timer
來實現循環功能。
class
TGTimerLoop
:
public
TGLoopBase
,
public
Osp::Base::Runtime::
ITimerEventListener
{
public
:
TGTimerLoop();
virtual
~TGTimerLoop();
result
Construct(
void
);
public
:
virtual
void
OnTimerExpired(Osp::Base::Runtime::
Timer
& timer);
public
:
void
Start();
void
Pause();
void
Stop();
private
:
Osp::Base::Runtime::
Timer
*
__pTimer
;
};
5
,循環實現
遊戲循環是在
TGTimerLoop
中實現的,主要在
OnTimerExpired()
函數中完成循環邏輯,其它的像
Start(),Pause(),Stop()
等函數對循環進行控制。
TGTimerLoop::TGTimerLoop
() :
__pTimer
(NULL)
{
}
TGTimerLoop::~TGTimerLoop
()
{
if
(__pTimer)
{
delete __pTimer
__pTimer = NULL
}
}
result
TGTimerLoop::Construct
(
void
)
{
result
r = E_SUCCESS;
__pTimer
=
new
Timer
();
r =
__pTimer
->
Construct
(*
this
);
return
r;
}
void
TGTimerLoop::OnTimerExpired
(Osp::Base::Runtime::
Timer
& timer)
{
long
long
startTime = 0;
Osp::System::
SystemTime
::
GetTicks
(startTime);
if
(
__pStatusListener
)
{
__pStatusListener
->HandleEvent();
__pStatusListener
->UpdateLogic(
__frameInterval
);
__pStatusListener
->Draw();
}
long
long
endTime = 0;
Osp::System::
SystemTime
::
GetTicks
(endTime);
long
long
deltaTime = endTime - startTime;
AppLog(
"deltaTime %ls"
,
LongLong
::
ToString
(deltaTime).
GetPointer
());
int
leftTime =
__frameInterval
- deltaTime;
if
(leftTime > 0)
{
__pTimer
->
Start
(leftTime);
}
else
{
__pTimer
->
Start
(1);
}
}
void
TGTimerLoop::Start
()
{
if
(
__pTimer
)
{
__pTimer
->
Cancel
();
__pTimer
->
Start
(
__frameInterval
);
}
}
void
TGTimerLoop::Pause
()
{
if
(
__pTimer
)
{
__pTimer
->
Cancel
();
}
}
void
TGTimerLoop::Stop
()
{
if
(
__pTimer
)
{
__pTimer
->
Cancel
();
}
}
其中的
OnTimerExpired()
函數中的代碼就是遊戲循環的關鍵代碼,從代碼中能夠看出這個實現的是上篇文章提到的「基於時間的固定間隔遊戲循環」。