Cocos2d-x 3.7 (實為 3.x 分支) 場景切換後黑屏,新場景 init() 未調用,通常是場景創建方式錯誤或Layer 未正確添加到 Scene。
createScene() 靜態工廠方法// GameScene.h
class GameScene : public cocos2d::Scene {
public:
static cocos2d::Scene* createScene(); // 工廠方法
virtual bool init(); // 初始化
CREATE_FUNC(GameScene); // 宏:生成 create() -> init() 流程
};
// GameScene.cpp
USING_NS_CC;
Scene* GameScene::createScene() {
auto scene = Scene::create(); // 1. 創建 Scene
auto layer = GameScene::create(); // 2. 創建 Layer (調用 init)
if (layer) {
scene->addChild(layer); // 3. 關鍵:Layer 加入 Scene
}
return scene;
}
bool GameScene::init() {
if (!Scene::init()) return false; // 必須調用父類 init
// 你的初始化代碼:添加精靈、按鈕、背景圖等
auto bg = Sprite::create("bg.png");
bg->setPosition(VisibleRect::center());
this->addChild(bg);
return true;
}
// 在 HelloWorld 或其他場景的按鈕回調中
void HelloWorld::onPlayButtonClicked(Ref* sender) {
auto scene = GameScene::createScene(); // 獲取完整 Scene
Director::getInstance()->replaceScene(TransitionFade::create(0.5f, scene));
// 或直接切換:Director::getInstance()->replaceScene(scene);
}
| 錯誤代碼 | 問題 | 修正 |
|---|---|---|
Director::getInstance()->replaceScene(GameScene::create()); | CREATE_FUNC 返回 Layer,非 Scene | 用 GameScene::createScene() 返回 Scene |
bool GameScene::init() { ... return true; } // 未調用 Scene::init() | 父類初始化缺失 | 首行 if (!Scene::init()) return false; |
auto layer = new GameScene(); layer->init(); scene->addChild(layer); | 手動 new/init 易漏釋放、autorelease | 用 GameScene::create() 自動管理內存 |
| 背景圖路徑錯誤 / 未加入場景 | 資源未發現或未 addChild | 檢查 Resources 目錄、路徑大小寫、addChild 調用 |
| VS2012 包含目錄未設置 | 編譯報錯找不到 cocos2d.h | 屬性 → VC++ 目錄 → 包含目錄添加 $(SolutionDir)cocos2d 等 |
$(SolutionDir)cocos2d
$(SolutionDir)cocos2d\cocos
$(SolutionDir)cocos2d\cocos\platform
$(SolutionDir)cocos2d\cocos\platform\win32
$(SolutionDir)external
$(SolutionDir)external\win32-specific\include
$(SolutionDir)cocos2d\prebuilt\win32\lib
// 在 init() 添加日志確認調用
bool GameScene::init() {
if (!Scene::init()) return false;
CCLOG("GameScene::init() called"); // 控制台輸出
// ...
return true;
}
// 檢查場景樹
auto runningScene = Director::getInstance()->getRunningScene();
CCLOG("Running scene: %s, children: %d",
typeid(*runningScene).name(), runningScene->getChildrenCount());
核心口訣:「createScene 造 Scene,create 造 Layer,addChild 連起來,init 必須調父類,切換用 replaceScene。」