【问题标题】:How can I popScene a specific Cocos2D scene from another scene?如何从另一个场景中弹出一个特定的 Cocos2D 场景?
【发布时间】:2013-06-01 22:07:52
【问题描述】:

我有一个自己开发的游戏,有三个场景:暂停菜单、主屏幕菜单和游戏本身。在游戏过程中,当游戏暂停时,它会调出暂停场景:

[[CCDirector sharedDirector] pushScene:[PauseScene node]];

从暂停场景来看,共有三个选项:重启、恢复、主菜单。单击恢复时,它只会弹出暂停场景并返回游戏场景以恢复游戏。单击主菜单时,它会将游戏场景保留在后台,并且从主菜单屏幕中,游戏仍在运行。到目前为止,经过大量研究,我还没有找到一种方法来从除游戏场景之外的任何场景中弹出场景(几乎将其从 RAM 中踢出)游戏场景。在暂停屏幕上,我可以使用:

[[CCDirector sharedDirector] popScene];

要摆脱暂停场景,如果我从游戏场景上的方法运行该代码,我可以摆脱该游戏实例,但我需要一种方法来弹出正在运行的游戏节点暂停节点的背景。总的来说,基本问题是:如何从另一个场景中弹出 Cocos2d 中的特定场景?

【问题讨论】:

    标签: iphone ios objective-c macos cocos2d-iphone


    【解决方案1】:

    Cocos2d 的场景切换主要有两个功能:pushScene/popScenereplaceScene

    1. 第一个是pushScene
    • (void) pushScene: (CCScene *) 场景

    暂停正在运行的场景的执行,将其压入堆栈 暂停的场景。将执行新场景。尽量避免大 推送场景堆栈以减少内存分配。仅在以下情况下调用它 有一个跑步的场景。

    此函数使用 stack 。它将所有场景存储在Last In-First Out (LIFO) 数据结构中。基本上它会覆盖场景并以它们出现的相反顺序将它们移除。这可能是您想要“推动”(或调出)暂停菜单,并“弹出”(删除)暂停场景以恢复游戏的内容。

    要返回一层,只需调用popScene

    • (void) popScene

    从队列中弹出一个场景。这个场景将取代正在运行的 一。正在运行的场景将被删除。如果没有更多的场景 堆栈执行终止。仅在存在时才调用它 跑步场景。

    2.我相信您会想要的另一个选项是replaceScene。这将停止当前正在运行的场景并用一个全新的场景替换它。这可能是您第一次结束游戏或从原始主菜单过渡到游戏玩法时想要的:

    • (void) replaceScene: (CCScene *) 场景

    用新的场景替换正在运行的场景。跑步场景是 终止。仅在有正在运行的场景时才调用它

    *请记住:谨慎使用pushScene。它将所有场景存储在内存中,以便以后可以将它们从堆栈中弹出。所以不要存储太多场景而忘记它们。

    **来源:cocos2D website

    编辑 1:

    您有几个选择。请记住,replaceScene 仅替换当前正在运行的场景,并且通常是您想要使用的。它不会“清除”整个场景堆栈,因此您通常很少想使用pushScene/popScene。在下面的演示中,我向您展示了两者的问题。不过,我确实会尽量节省内存。

    使用 push/popScene:

    1.从主屏幕开始运行。

    2.当用户单击“播放”按钮时,使用replaceScene 停止主屏幕场景并开始运行游戏播放场景(请记住,主屏幕将不再运行或保存在内存中的任何位置。如果它必须记住任何信息,然后使用pushScene 将其保存到堆栈中。我这样做的原因是因为主屏幕可能每次都相同,并且在我们玩游戏时不需要继续运行)。

    3.用户现在可以玩一会儿了。然后他们想停下来上个厕所。他们单击“暂停”按钮。然后使用pushScene 保存Game Play 场景的当前状态并开始运行Pause Menu 场景。 (可以说游戏是“暂停”的)。 您的堆栈现在如下所示:

    //Bottom ----------------------> Top

    [Game Play scene], [Pause Menu Scene]

    4.暂停片刻后,他们可以使用pushScene从内存中删除暂停菜单场景,并加载“暂停”的游戏场景并立即恢复播放。

    那么问题就变成了,好吧,如果你想从暂停 -> 主菜单去怎么办。如果您只是在暂停菜单上使用replaceScene,那么旧游戏将留在记忆中。您需要找到一种方法来清除旧的 Game Play 场景。

    另一种选择是保留主屏幕,方法是使用pushScene 将其保留在堆栈中,然后弹出两次。根据我的经验,这通常会导致“跳跃”的过渡。

    首选的方法往往是:创建一个Singleton Class 并在您暂停时保存内存。 (单例类只是一个只有一个实例的类。它基本上是我们的“当前游戏状态”数据。我推荐这个 tutorial。)

    使用替换场景:

    1.从主屏幕开始运行。

    2.当用户单击“播放”按钮时,使用replaceScene 停止主屏幕场景并开始运行游戏播放场景(请记住,主屏幕将不再运行或保存在内存中的任何位置。如果它必须记住任何信息,然后有一部分Singleton Class 用于主屏幕数据)。

    3.用户现在可以玩一会儿了。然后他们想停下来上个厕所。他们单击“暂停”按钮。立即“暂停”您的游戏并将所有必要的精灵、游戏逻辑等保存到Singleton Class,然后使用replaceScene 退出游戏播放场景并加载暂停场景。然后根据他们的选择,您要么继续游戏(第 4 步),要么转到主屏幕(第 5 步)

    4.从 Singleton ClassreplaceScene 重新加载渲染游戏所需的所有内容,以退出暂停菜单并加载 Game Play 场景。

    5.使用replaceScene退出暂停菜单并加载主屏幕。

    【讨论】:

    • 谢谢。我了解所有不同场景更改的工作原理,但我仍然需要知道如何从另一个场景中弹出一个特定场景。
    • 你能告诉我你想运行的场景的顺序吗? “流行音乐”不会改变场景。它只是删除最后一次“推送”并恢复该“推送”之前仍在运行(并临时存储在内存中)之前的最近场景。
    • Home Screen-> GamePlay-> Pause-> Home Screen 问题是我需要从暂停屏幕中踢出在后台暂停的游戏场景。它继续在流程图中最后一个主屏幕的后台运行。
    • 我更新了。我还在做一些校对和清理工作。但它应该有望回答你的问题。如果不清楚或不完全是您要查找的内容,请告诉我!
    • 还有 popToRootScene: 和 popToSceneStackLevel:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多