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()
函数中的代码就是游戏循环的关键代码,从代码中能够看出这个实现的是上篇文章提到的“基于时间的固定间隔游戏循环”。