cocos2d-x 中 定时器1帧需要多长时间
1个回答
推荐于2016-01-09 · 知道合伙人影视综艺行家
关注
展开全部
在游戏中,有一个比较重要的桥虚并概誉念念就是定时调度。简单来说就是当一个游戏在运行过程中,我们需要通过控制时间间隔来响应一些所需要的时间,从而形成整个游戏的主循环。cocos2d-x中为我们定义了个定时调度器CCScheduler,它是一个管理所有节点定时器的类,负责记录定时器,并在合适的时间触发定时事件。下图为CCScheduler的主要成员
打开源代码,我们会发现在游戏主循环中会一直调用m_pScheduler的update方法,我们可以轻易发现m_pScheduler是CCScheduler的一个对象,也就是说主循环通过update方法来实现定时调度,我们进一步分析CCScheduler::update的源敏迹代码如下:
[csharp] view plaincopy
void CCScheduler::update(float dt)
{
m_bUpdateHashLocked = true;
if (m_fTimeScale != 1.0f)
{
dt *= m_fTimeScale;
}
// Iterate over all the Updates' selectors 枚举所有的Update定时器
tListEntry *pEntry, *pTmp;
// updates with priority < 0 优先级小于0
DL_FOREACH_SAFE(m_pUpdatesNegList, pEntry, pTmp)
{
if ((! pEntry->paused) && (! pEntry->markedForDeletion))
{
pEntry->target->update(dt);
}
}
// updates with priority == 0 优先级等于0
DL_FOREACH_SAFE(m_pUpdates0List, pEntry, pTmp)
{
if ((! pEntry->paused) && (! pEntry->markedForDeletion))
{
pEntry->target->update(dt);
}
}
// updates with priority > 0 优先级大于0
DL_FOREACH_SAFE(m_pUpdatesPosList, pEntry, pTmp)
{
if ((! pEntry->paused) && (! pEntry->markedForDeletion))
{
pEntry->target->update(dt);
}
}
// Iterate over all the custom selectors 枚举所有自定义的定时器
for (tHashTimerEntry *elt = m_pHashForTimers; elt != NULL; )
{
m_pCurrentTarget = elt;
m_bCurrentTargetSalvaged = false;
if (! m_pCurrentTarget->paused)
{
// The 'timers' array may change while inside this loop
for (elt->timerIndex = 0; elt->timerIndex < elt->timers->num; ++(elt->timerIndex))
{
elt->currentTimer = (CCTimer*)(elt->timers->arr[elt->timerIndex]);
elt->currentTimerSalvaged = false;
elt->currentTimer->update(dt);
if (elt->currentTimerSalvaged)
{
// The currentTimer told the remove itself. To prevent the timer from
// accidentally deallocating itself before finishing its step, we retained
// it. Now that step is done, it's safe to release it.
elt->currentTimer->release();
}
elt->currentTimer = NULL;
}
}
// elt, at this moment, is still valid
// so it is safe to ask this here (issue #490)
elt = (tHashTimerEntry *)elt->hh.next;
// only delete currentTarget if no actions were scheduled during the cycle (issue #481)
if (m_bCurrentTargetSalvaged && m_pCurrentTarget->timers->num == 0)
{
removeHashElement(m_pCurrentTarget);
}
}
// Iterate over all the script callbacks 处理脚本相关事件
if (m_pScriptHandlerEntries)
{
for (int i = m_pScriptHandlerEntries->count() - 1; i >= 0; i--)
{
CCSchedulerScriptHandlerEntry* pEntry = static_cast<CCSchedulerScriptHandlerEntry*>(m_pScriptHandlerEntries->objectAtIndex(i));
if (pEntry->isMarkedForDeletion())
{
m_pScriptHandlerEntries->removeObjectAtIndex(i);
}
打开源代码,我们会发现在游戏主循环中会一直调用m_pScheduler的update方法,我们可以轻易发现m_pScheduler是CCScheduler的一个对象,也就是说主循环通过update方法来实现定时调度,我们进一步分析CCScheduler::update的源敏迹代码如下:
[csharp] view plaincopy
void CCScheduler::update(float dt)
{
m_bUpdateHashLocked = true;
if (m_fTimeScale != 1.0f)
{
dt *= m_fTimeScale;
}
// Iterate over all the Updates' selectors 枚举所有的Update定时器
tListEntry *pEntry, *pTmp;
// updates with priority < 0 优先级小于0
DL_FOREACH_SAFE(m_pUpdatesNegList, pEntry, pTmp)
{
if ((! pEntry->paused) && (! pEntry->markedForDeletion))
{
pEntry->target->update(dt);
}
}
// updates with priority == 0 优先级等于0
DL_FOREACH_SAFE(m_pUpdates0List, pEntry, pTmp)
{
if ((! pEntry->paused) && (! pEntry->markedForDeletion))
{
pEntry->target->update(dt);
}
}
// updates with priority > 0 优先级大于0
DL_FOREACH_SAFE(m_pUpdatesPosList, pEntry, pTmp)
{
if ((! pEntry->paused) && (! pEntry->markedForDeletion))
{
pEntry->target->update(dt);
}
}
// Iterate over all the custom selectors 枚举所有自定义的定时器
for (tHashTimerEntry *elt = m_pHashForTimers; elt != NULL; )
{
m_pCurrentTarget = elt;
m_bCurrentTargetSalvaged = false;
if (! m_pCurrentTarget->paused)
{
// The 'timers' array may change while inside this loop
for (elt->timerIndex = 0; elt->timerIndex < elt->timers->num; ++(elt->timerIndex))
{
elt->currentTimer = (CCTimer*)(elt->timers->arr[elt->timerIndex]);
elt->currentTimerSalvaged = false;
elt->currentTimer->update(dt);
if (elt->currentTimerSalvaged)
{
// The currentTimer told the remove itself. To prevent the timer from
// accidentally deallocating itself before finishing its step, we retained
// it. Now that step is done, it's safe to release it.
elt->currentTimer->release();
}
elt->currentTimer = NULL;
}
}
// elt, at this moment, is still valid
// so it is safe to ask this here (issue #490)
elt = (tHashTimerEntry *)elt->hh.next;
// only delete currentTarget if no actions were scheduled during the cycle (issue #481)
if (m_bCurrentTargetSalvaged && m_pCurrentTarget->timers->num == 0)
{
removeHashElement(m_pCurrentTarget);
}
}
// Iterate over all the script callbacks 处理脚本相关事件
if (m_pScriptHandlerEntries)
{
for (int i = m_pScriptHandlerEntries->count() - 1; i >= 0; i--)
{
CCSchedulerScriptHandlerEntry* pEntry = static_cast<CCSchedulerScriptHandlerEntry*>(m_pScriptHandlerEntries->objectAtIndex(i));
if (pEntry->isMarkedForDeletion())
{
m_pScriptHandlerEntries->removeObjectAtIndex(i);
}
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询