Cocos2d-x 系列四:常用控件與場景管理實戰
核心架構啟動流程
// main.cpp
int main() {
AppDelegate app;
return Application::getInstance()->run();
}
// AppDelegate::applicationDidFinishLaunching()
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if (!glview) { glview = GLView::create("Game"); director->setOpenGLView(glview); }
director->setDisplayStats(true);
director->setAnimationInterval(1.0/60);
Scene* scene = Scene::create();
Layer* layer = Layer::create();
scene->addChild(layer);
director->runWithScene(scene); // 首次運行
// 後續切換用 director->replaceScene(newScene);
文本顯示與輸入
LabelTTF - 靜態文本
auto label = LabelTTF::create("Hello cocos2d-x", "Arial", 36);
label->setPosition(visibleSize.width/2, visibleSize/2);
layer->addChild(label);
TextFieldTTF - 文本輸入框
auto tf = TextFieldTTF::textFieldWithPlaceHolder("input here", "Arial", 20);
tf->setPosition(visibleSize.width/2, visibleSize/2);
layer->addChild(tf);
// 觸摸事件啟用輸入法
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = [tf](Touch* t, Event* e) {
if (tf->getBoundingBox().containsPoint(t->getLocation()))
tf->attachWithIME(); // 彈出鍵盤
else
tf->detachWithIME(); // 收起鍵盤
return false;
};
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, tf);
消息提示
log("format %d", val):跨平台日誌輸出
MessageBox("內容", "標題"):原生彈窗
自定義節點類 (繼承 Sprite)
// Ball.h
class Ball : public Sprite {
public:
CREATE_FUNC(Ball); // 靜態 create() 工廠方法
virtual bool init() { return initWithFile("Ball.jpg"); }
};
// 使用
auto ball = Ball::create();
ball->setPosition(200, 200);
scene->addChild(ball);
TableView - 列表視圖 (類比 Android ListView)
// 繼承 Layer, TableViewDataSource, TableViewDelegate
class HelloWorld : public Layer, public TableViewDataSource, public TableViewDelegate {
// DataSource 必須實現
virtual Size cellSizeForTable(TableView* table) { return Size(300, 50); }
virtual TableViewCell* tableCellAtIndex(TableView* table, ssize_t idx) {
TableViewCell* cell = table->dequeueCell();
LabelTTF* label;
if (!cell) {
cell = TableViewCell::create();
label = LabelTTF::create("", "Arial", 20);
label->setTag(2); cell->addChild(label);
} else label = (LabelTTF*)cell->getChildByTag(2);
label->setString(StringUtils::format("Label %zd", idx));
return cell;
}
virtual ssize_t numberOfCellsInTableView(TableView* table) { return 100; }
// Delegate 可選實現
virtual void tableCellTouched(TableView* table, TableViewCell* cell) {
auto label = (LabelTTF*)cell->getChildByTag(2);
log("Clicked: %s", label->getString().c_str());
}
};
// 創建 TableView
auto tv = TableView::create(this, Size(300, 300));
tv->setAnchorPoint(Vec2(0,0));
tv->setPosition(100, 0);
tv->setDelegate(this);
addChild(tv);
Menu - 選單系統
auto item1 = MenuItemImage::create("normal.png", "pressed.png",
[](Ref* sender){ log("Menu 1 clicked"); });
auto item2 = MenuItemImage::create("pressed.png", "normal.png",
[](Ref* sender){ log("Menu 2 clicked"); });
item1->setPosition(visibleSize.width/2 - 60, visibleSize/2 - 40);
item2->setPosition(visibleSize.width/2 - 60, visibleSize/2 - 100);
auto menu = Menu::create(item1, item2, nullptr);
addChild(menu);

場景切換動畫
// 直接替換 (無動畫)
director->replaceScene(NewScene::createScene());
// 帶轉場動畫 (1 秒淡入左下)
director->replaceScene(TransitionFadeBL::create(1.0f, NewScene::createScene()));
// 常用轉場類
// TransitionFade, TransitionMoveInL/R/T/B, TransitionSlideInL/R/T/B,
// TransitionZoomFlipX/Y, TransitionPageTurn, TransitionCrossFade...
節點層級結構
Scene (場景)
└── Layer (圖層,觸摸響應)
├── Sprite (精靈,圖片)
├── Label (文本)
├── Menu (選單)
├── TableView (列表)
├── ParticleSystem (粒子)
└── 自定義 Node