ゲームシーンの一時停止をonExit()で実現

3133 ワード

ゲームの一時停止は簡単な機能ですが、実際のプロジェクトでしか使用できません.だからこんなに長い間勉強して、やっとここで困難にぶつかった.本の中で説明していないで、ネット上で資料を調べて、3つの解決策を得ました:
1.Directorのpauseメソッドを使用する.
2.スクリーンショットを保存してから、背景がこのショットである別のシーンをpushします.RenderTextureダイナミックテクスチャクラスを使用してスクリーンショットを保存します.
3.ノードを巡回し、onExit()インタフェースを呼び出します.
まず、前の2つのソリューションについて説明します.最初はなぜか分からないが、有効にするとカートンが現れ、私が望んでいた一時停止効果ではない.2つ目の案は、一時停止シーンクラスを1つ多く書くことで、ゲーム体験に必要なゲームはもちろん少なくないが、普通のボタン一時停止方式には向いていない.
ここで3つ目の案をまとめます.それはonExitを使うことです.公式ドキュメントによると、Node呼び出しonExitインタフェースは、「ステージを終了」するときに呼び出されます.この解釈は本当に具体的ではありませんが、舞台を引退したときはいったい何をしましたか.ソースコードを表示するしかありません.ノードのonExitメソッドには、2つの重要なコードがあります.
this->pause();
for( const auto &child: _children)
        child->onExit();

1つのノードonExitの後、そのサブノードもすべてonExitであり、pauseメソッドも呼び出されていることがわかりますが、pauseメソッドは何をしていますか?コードを見てください:
void Node::pause()
{
    _scheduler->pauseTarget(this);
    _actionManager->pauseTarget(this);
    _eventDispatcher->pauseEventListenersForTarget(this);
}

1.ノードのscheduleを一時停止しました.2.当該ノードの動作を一時停止した;3.ノードのイベントリスニングを一時停止しました.
つまり、レンダリング以外のすべてのダイナミック機能はほとんど一時停止されます.onExitの本質はコールバック関数であり、ノードがステージを終了するときに呼び出され、機能はノードを「終了」させることであることが明らかになった.コールバック関数ですが、手動で呼び出すことができます.
質問に戻ります:どのようにゲームのシーンを一時停止させますか?
シーン内のマスターLayerはノードであり、マスターLayerがonExitを呼び出すと、すべてのサブノードが一時停止します.しかし、ボタンのような「残業」が必要なノードは常にあります.一時停止ボタンもonExitにすれば、ゲームを再開することはできません.この方法を解決するのも簡単です.それは、サブノードを巡回することによって、それらを1つずつonExitで一時停止し、一時停止を必要としないサブノードを排除することです.これにより,主Layerは一時停止しなかったが,そのすべての一時停止したサブノードはすべて一時停止した.
コードを参照:
auto vec = this->getChildren();
for (auto &child : vec)
{
    if (child->getTag() != PAUSE_MENU)
        child->onExit();
}

これにより、基本的に一時停止機能が完了します.しかし、もう2つの重要な点は、一時停止に致命的な影響を与えることです.それは、
1.主Layerのイベント傍受はまだ閉じていないが、タッチなどのイベントを受信している.
2.シーンに物理世界がある場合、物理世界はまだ一時停止されておらず、物理シミュレーションは継続しています.
したがって、実際の一時停止を完了するには、2行のコードを複数呼び出す必要があります.
_eventDispatcher->pauseEventListenersForTarget(this);

((Scene*)this->getParent())->getPhysicsWorld()->setAutoStep(false);

これで完全な一時停止効果が完了しました.しかも効率が速く見え、実際の操作にもカートンは現れなかった.最后にゲームを再开して、とても简単で、逆にonEnterを呼び出すことができます:ノード达、着工しました!