Cocos2d-x 3.Xの中のスケジューラとupdate()
2650 ワード
Cocos2d-x 3.XにはデフォルトスケジューラscheduleUpdate()とカスタムスケジューラschedule()と単一スケジューラscheduleOnce()の3種類があります.これらはすべてノードクラスメンバー関数です.これらはまた、単一のモードのSchedulerクラスに対応する3つのスケジューラをそれぞれ呼び出します.ノード内のスケジューラでイベントをスケジュールしたり、総スケジューラSchedulerでイベントをスケジュールしたりすることができます.ただし、両者のパラメータ(スケジューリングオブジェクト)が異なることに注意してください.
たとえば、レイヤー、スプライトなどのノードサブクラスオブジェクトがノードのscheduleUpdate()を呼び出している場合(パラメータなし)、サブクラスのupdate()関数を最初にスケジューリングし、サブクラスにupdate()がない場合、ノードのupdate()関数をスケジューリングします.
CCNode.cpp
ここではcomponentContainerを呼び出しているのを見ました.コントローラコントローラ内のupdate()はここで呼び出されます.ただし(2回目)、update()が布団クラスに書き換えられると、サブクラスオブジェクトがサブクラスのupdate()関数をスケジューリングし、ComController内のupdate()は呼び出されなくなります.この部分も書き直さない限り、この点に注意してください.
SchedulerのscheduleUpdate(T*target,int priority,bool paused)を直接呼び出す場合は、指定したオブジェクトのupdate()関数を起動するスケジューリングオブジェクトを指定する必要があります.
ここでは、オブジェクト向けのプログラミングで注意しなければならない点について説明します.親オブジェクトは親関数しか呼び出せません.サブクラスオブジェクト呼び出し(親関数によって間接的に呼び出された場合でも)は、まずサブクラス関数です.サブクラスに定義がない限り、親関数を呼び出すことはできません.この例では、サブクラスオブジェクトが親ノードのscheduleUpate()関数(サブクラスでも書き換えることができます)を先に呼び出し、サブクラスで書き換えたupdate()関数を呼び出すこともできます.(updateは虚関数でなければなりません.そうしないと、親クラスで宣言が見つかりません)(3回目).
親クラスの純虚関数は、クラスオブジェクトによってのみ呼び出されます.ただし、サブクラスオブジェクトのタイプを親クラスタイプに変換すると、サブクラスで定義された(親クラスで宣言された)純虚関数を呼び出すことができますが、本質的にはサブクラスオブジェクトです(メモリ割り当てから).
scheduleUpdate()を使用する場合は、次の2つの問題に注意してください.
1)スケジューラの呼び出し方法
scheduleUpdate()は、あるシーンまたはレイヤーで直接手動で呼び出すことができます.ただし、次の2つの関数は、ComControllerを使用すると自動的に呼び出されます.
CCNode.cpp
CCComController.cpp
2)どのupdate()をスケジューリングするか
前述したように、Nodeサブクラス(レイヤー、スプライトなど)のupdate()かComControllerのupdate()か(Nodeのupdate()で呼び出される)に注意してください.
レベルが限られていて、もし妥当でないならば、レンガを撮ることを歓迎します!
たとえば、レイヤー、スプライトなどのノードサブクラスオブジェクトがノードのscheduleUpdate()を呼び出している場合(パラメータなし)、サブクラスのupdate()関数を最初にスケジューリングし、サブクラスにupdate()がない場合、ノードのupdate()関数をスケジューリングします.
CCNode.cpp
// override me
void Node::update(float fDelta)
{
#if CC_ENABLE_SCRIPT_BINDING
if (0 != _updateScriptHandler)
{
//only lua use
SchedulerScriptData data(_updateScriptHandler,fDelta);
ScriptEvent event(kScheduleEvent,&data);
ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);
}
#endif
if (_componentContainer && !_componentContainer->isEmpty())
{
_componentContainer->visit(fDelta);
}
}
ここではcomponentContainerを呼び出しているのを見ました.コントローラコントローラ内のupdate()はここで呼び出されます.ただし(2回目)、update()が布団クラスに書き換えられると、サブクラスオブジェクトがサブクラスのupdate()関数をスケジューリングし、ComController内のupdate()は呼び出されなくなります.この部分も書き直さない限り、この点に注意してください.
SchedulerのscheduleUpdate(T*target,int priority,bool paused)を直接呼び出す場合は、指定したオブジェクトのupdate()関数を起動するスケジューリングオブジェクトを指定する必要があります.
ここでは、オブジェクト向けのプログラミングで注意しなければならない点について説明します.親オブジェクトは親関数しか呼び出せません.サブクラスオブジェクト呼び出し(親関数によって間接的に呼び出された場合でも)は、まずサブクラス関数です.サブクラスに定義がない限り、親関数を呼び出すことはできません.この例では、サブクラスオブジェクトが親ノードのscheduleUpate()関数(サブクラスでも書き換えることができます)を先に呼び出し、サブクラスで書き換えたupdate()関数を呼び出すこともできます.(updateは虚関数でなければなりません.そうしないと、親クラスで宣言が見つかりません)(3回目).
親クラスの純虚関数は、クラスオブジェクトによってのみ呼び出されます.ただし、サブクラスオブジェクトのタイプを親クラスタイプに変換すると、サブクラスで定義された(親クラスで宣言された)純虚関数を呼び出すことができますが、本質的にはサブクラスオブジェクトです(メモリ割り当てから).
scheduleUpdate()を使用する場合は、次の2つの問題に注意してください.
1)スケジューラの呼び出し方法
scheduleUpdate()は、あるシーンまたはレイヤーで直接手動で呼び出すことができます.ただし、次の2つの関数は、ComControllerを使用すると自動的に呼び出されます.
CCNode.cpp
bool Node::addComponent(Component *component)
{
// lazy alloc
if (!_componentContainer)
_componentContainer = new (std::nothrow) ComponentContainer(this);
// should enable schedule update, then all components can receive this call back
scheduleUpdate();
return _componentContainer->add(component);
}
CCComController.cpp
void ComController::onEnter()
{
if (_owner != nullptr)
{
_owner->scheduleUpdate();
}
}
2)どのupdate()をスケジューリングするか
前述したように、Nodeサブクラス(レイヤー、スプライトなど)のupdate()かComControllerのupdate()か(Nodeのupdate()で呼び出される)に注意してください.
レベルが限られていて、もし妥当でないならば、レンガを撮ることを歓迎します!