You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Cocos2d场景切换失败:仅显示首个场景,求代码问题排查

问题分析与解决方案

嘿,我一眼就瞅出你代码里的问题啦!

核心问题所在

你写的这段代码里,director.run(first_scene)是用来启动Cocos2d的主事件循环的,这行代码会直接阻塞当前线程——也就是说,一旦主循环开始运行,后面的director.replace(second_scene)根本没机会被执行到,所以你的第二个场景永远不会被加载出来。

怎么解决?

要切换场景,你得通过Cocos2d的事件系统或者调度器来触发,比如设置一个延迟自动切换,或者通过键盘/触摸事件手动触发。下面给你两种可行的修改方案:

方案1:延迟自动切换场景

给第一个场景的Layer添加一个调度器,延迟几秒后自动切换到第二个场景:

import cocos
from cocos.scene import Scene
from cocos.director import director

class HelloCocos(cocos.layer.Layer):
    def __init__(self, text):
        super().__init__()
        self.text = text
        size = director.get_window_size()
        label = cocos.text.Label(self.text + " (Will switch in 3s)", font_name="Times New Roman", font_size=32)
        label.position = size[0] / 2, size[1] / 2
        self.add(label)
        
        # 调度器:延迟3秒执行切换场景的方法
        self.schedule_once(self.switch_scene, delay=3)

    def switch_scene(self, dt):
        second_scene = Scene(HelloCocos2("end cocos"))
        director.replace(second_scene)

class HelloCocos2(cocos.layer.Layer):
    def __init__(self, text):
        super().__init__()
        self.text = text
        size = director.get_window_size()
        label = cocos.text.Label(self.text, font_name="Times New Roman", font_size=32)
        label.position = size[0] / 3, size[1] / 3
        self.add(label)

director.init(width=1280, height=800, caption="my cocos window")
first_scene = Scene(HelloCocos("hello cocos"))
director.run(first_scene)

方案2:通过键盘事件手动切换

让第一个场景监听键盘按键,按下任意键就切换到第二个场景:

import cocos
from cocos.scene import Scene
from cocos.director import director

class HelloCocos(cocos.layer.Layer):
    is_event_handler = True  # 必须设置这个标记,才能接收事件

    def __init__(self, text):
        super().__init__()
        self.text = text
        size = director.get_window_size()
        label = cocos.text.Label(self.text + " (Press any key to switch)", font_name="Times New Roman", font_size=32)
        label.position = size[0] / 2, size[1] / 2
        self.add(label)

    def on_key_press(self, key, modifiers):
        # 监听按键按下事件,触发场景切换
        second_scene = Scene(HelloCocos2("end cocos"))
        director.replace(second_scene)

class HelloCocos2(cocos.layer.Layer):
    def __init__(self, text):
        super().__init__()
        self.text = text
        size = director.get_window_size()
        label = cocos.text.Label(self.text, font_name="Times New Roman", font_size=32)
        label.position = size[0] / 3, size[1] / 3
        self.add(label)

director.init(width=1280, height=800, caption="my cocos window")
first_scene = Scene(HelloCocos("hello cocos"))
director.run(first_scene)

为什么这样能行?

Cocos2d的主循环会持续处理帧更新和事件回调,调度器的schedule_once会在指定延迟后,把切换场景的逻辑放到主循环的下一帧中执行;而键盘事件的回调函数也是在主循环的事件处理阶段被调用的——这样就能保证场景切换的代码被正确执行啦。

内容的提问来源于stack exchange,提问作者xin yu

火山引擎 最新活动