一,
帧与帧之间时间间隔
/* 标记是否下次帧逻辑时是否清除(忽略)_deltaTime */
bool _nextDeltaTimeZero;
/* 上一次逻辑帧运行到当前的时间间隔,用来判断是否应该进行下次逻辑帧,上一次帧执行的时间记录在 _lastUpdate 变量里面*/
float _deltaTime;
下面两个函数是用来操作下一次的 _deltaTime是否有效的,当整个游戏暂停的时候,这时_deltaTime会不断累计,就会用到了_nextDeltaTimeZero这个变量,标记着下次的_deltaTime为0这样就会不出现恢复暂停后跳帧,而是继续当前帧顺序开始。
inline bool isNextDeltaTimeZero() { return _nextDeltaTimeZero; }
void setNextDeltaTimeZero(bool nextDeltaTimeZero);
计算_deltaTime的函数,会在每个逻辑循环里面都调用。
/** 计算 deltaTime 上次逻辑帧调用的时间和当前时间的时间间隔。如果 nextDeltaTimeZero为true则deltaTime为0*/
void calculateDeltaTime();
/*
上次主循环帧执行到当前的时间间隔 _deltaTime
*/
float getDeltaTime()
const;
二,
Scene管理
/* 当前正在执行的场景,由这个变量可以知道,Cocos2d-x同一时间只能执行一个场景。*/
Scene *_runningScene;
/* 下一个要执行的场景,这块肯定是在场景切换的时候要用到的 */
Scene *_nextScene;
/* 是否清除场景的标记,当为真时,旧的场景就收到清除消息 */
bool _sendCleanupToScene;
/* 场景的堆栈 */
Vector _scenesStack;
Cocos2d-x同时只能执行一个场景,场景切换的时候有一个 _nextScene。清除场景时有一个标记 _scendCleanupToScene,等待执行的场景都存在 一个栈里面 _scenesStack
/** 通过调用 `popToSceneStackLevel(1)` 这个方法来实现清理栈里的场景只留下根场景,就是剩下第一个入栈的场景 */
void popToRootScene();
/** 按栈的层次来清理栈里的场景,level=0全清除 =1时 为 popToRootScene() 如果值超出了栈里的场景数量则不处理 */
void popToSceneStackLevel(int level);
/*
* 清除Direct的内存缓存,看下源码可以大概了解都有字体,纹理,文件等内存资源
*/
void
purgeCachedData();
/*
* 设置默认值,具体有哪些看下代码就知道了,很清楚写的
*/
void setDefaultValues();
三,整个游戏的循环
int
Application
::run()
{
initGLContextAttrs();
if(!applicationDidFinishLaunching()) //没初始化成功
{
return
1
;
}
// Retain glview to avoid glview being released in the while loop
glview->
retain
();
while
(!glview->
windowShouldClose
())
{
lastTime = getCurrentMillSecond(); //当前帧开始的时间
director->mainLoop(); //一个游戏循环内的所有事件和内容
glview->
pollEvents
();
curTime = getCurrentMillSecond(); //执行完一个循环后的时间
if
(curTime - lastTime <
_animationInterval
) //相减得到绘制一帧所需要的时间,如果小于设置的帧率时间,
{ //则休眠,直至下一次循环更新的时间
usleep
(
static_cast
<
useconds_t
>((
_animationInterval
- curTime + lastTime)*
1000
));
}
}
ps: 帧率是指程序中画面的绘制速度,通常称为每秒帧数,cocos2dx中默认为60fps
virtual
void
setAnimationInterval(
double
interval) //设置方法,参数为帧率倒数,1.0/60
tips:
application里面有一个run方法 ,在run方法里面有一个死循环,那个是游戏的主循环,在那个死循环里不断的调用 director->mainLoop这个就是在主游戏循环里不断的执行逻辑帧的操作.
四,内存
/** Removes all cocos2d cached data.
void
purgeCachedData(); //清除内存缓存
/** Sets the default values based on the Configuration info. */
void setDefaultValues();//设置默认值(字体,纹理等等)
五,OpenGL操作
/** Sets the OpenGL default values.
void
setGLDefaultValues();//设置OpenGL默认值
/** Enables/disables OpenGL alpha blending.
void
setAlphaBlending(
bool
on);//设置是否开启透明
/** Sets clear values for the color buffers,
void
setClearColor(
const
Color4F
& clearColor);
/** Enables/disables OpenGL depth test. */
void setDepthTest(bool on);//是否开启深度测试
六,单例及初始化子类
Director
*
Director
::getInstance()
{
if
(!
s_SharedDirector
)
{
s_SharedDirector
=
new
(
std
::
nothrow
)
DisplayLinkDirector
();
s_SharedDirector
->
init
();//初始化了事件,定时器,渲染器等等等等
}
return
s_SharedDirector
;
}
DisplayLinkDirector类为Director的子类
在这个类中实现了几个Director中关键的虚函数
virtual
void
mainLoop()
override
;
virtual
void
setAnimationInterval(
double
value)
override
;
virtual
void
startAnimation()
override
;
virtual void stopAnimation() override;
void
DisplayLinkDirector
::mainLoop()
{
if
(
_purgeDirectorInNextLoop
)
{
_purgeDirectorInNextLoop
=
false
; //判断是否应该清除Director
purgeDirector
();
}
else
if
(
_restartDirectorInNextLoop
)
{
_restartDirectorInNextLoop
=
false
;
restartDirector
();
}
else
if
(!
_invalid
)//判断是否进行逻辑循环
{
drawScene(); //渲染
// release the objects
PoolManager
::
getInstance
()->
getCurrentPool
()->
clear
();//release内存池元素
}
}
void
Director
::drawScene()
{
// calculate "global" dt
calculateDeltaTime();//计算帧之间的时间间隔,根据这个时间间隔判断进行什么操作
if
(
_openGLView
)
{
_openGLView
->
pollEvents
();
}
if
(!
_paused
)//没有暂停情况下,更新计时器,分发更新后的消息
{
_scheduler
->
update
(
_deltaTime
);
_eventDispatcher
->
dispatchEvent
(
_eventAfterUpdate
);
}
//OpenGL清理
_renderer
->
clear
();
experimental
::
FrameBuffer
::
clearAllFBOs
();
if
(
_nextScene
)//设置下一个场景
{
setNextScene
();
}
pushMatrix
(
MATRIX_STACK_TYPE
::
MATRIX_STACK_MODELVIEW
);
if
(
_runningScene
)
{
#if (CC_USE_PHYSICS || (CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION) || CC_USE_NAVMESH)
_runningScene
->
stepPhysicsAndNavigation
(
_deltaTime
);
#endif
//clear draw stats
_renderer
->
clearDrawStats
();
//render the scene渲染场景
_runningScene
->
render
(
_renderer
);
//分发渲染后的消息
_eventDispatcher
->
dispatchEvent
(
_eventAfterVisit
);
}
// draw the notifications node
if
(
_notificationNode
)
{
_notificationNode
->
visit
(
_renderer
,
Mat4
::
IDENTITY
,
0
);
}
if
(
_displayStats
)
{
showStats
();
}
_renderer
->
render
();
_eventDispatcher
->
dispatchEvent
(
_eventAfterDraw
);
popMatrix
(
MATRIX_STACK_TYPE
::
MATRIX_STACK_MODELVIEW
);
_totalFrames
++;
// swap buffers
if
(
_openGLView
)
{
_openGLView
->
swapBuffers
();
}
if
(
_displayStats
)
{
calculateMPF
();
}
}
七,
/** Director will trigger an event when projection type is changed. */
static
const
char
*EVENT_PROJECTION_CHANGED;
/** Director will trigger an event after Schedule::update() is invoked. */
static
const
char
* EVENT_AFTER_UPDATE;
/** Director will trigger an event after Scene::render() is invoked. */
static
const
char
* EVENT_AFTER_VISIT;
/** Director will trigger an event after a scene is drawn, the data is sent to GPU. */
static const char* EVENT_AFTER_DRAW;
事件类型:changed,update,visit,draw
待补充