首先要准备一张看起来有大作水准的图片,最好带有火焰色彩的,然后准备几个按钮素材,最后是一首激情澎湃的BGM.
我们要做的效果是利用cocos2d-x的物理引擎打造一片火海的效果。cocos2d-x提供了很强的物理引擎,给我们提供了相当多的粒子效果。按照传统的图形算法实现粒子特效,是一种体力活。物理引擎主要作用是提供粒子发射器,粒子有属于自己的运动规则,如果N个粒子一起运动,就变成了带有物理规则的特效。

场景代码:
TitleMenuScene.h:

[cpp]

#ifndef HELLOWORLD_SCENE_H

#define HELLOWORLD_SCENE_H

#include "cocos2d.h"

class TitleMenu : public cocos2d::Layer
{
public:
// Here’s a difference. Method ‘init’ in cocos2d-x returns bool, instead of returning ‘id’ in cocos2d-iphone
virtual bool init();

// there's no 'id' in cpp, so we recommend returning the class instance pointer
static cocos2d::Scene* scene();

// a selector callback
void startGameCallback(Object* sender);
void loadGameCallback(Object* sender);
void creditsCallback(Object* sender);
void exitGameCallback(Object* sender);

// implement the "static node()" method manually
CREATE_FUNC(TitleMenu);

};

#endif // HELLOWORLD_SCENE_H
[/cpp]

TitleMenuScene.cpp

[cpp]

#include "TitleMenuScene.h"

#include "CodePage.hpp"

#include "SimpleAudioEngine.h"

USING_NS_CC;

Scene TitleMenu::scene()
{
// ‘scene’ is an autorelease object
Scene
scene = Scene::create();

// 'layer' is an autorelease object
TitleMenu *layer = TitleMenu::create();

// add layer as a child to scene
scene->addChild(layer);

// return the scene
return scene;

}

bool TitleMenu::init()
{
if ( !Layer::init() )
{
return false;
}

Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();

//播放背景音乐
CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic("Audio/BGM/attack_on_titan.mp3", true);

//画背景图
Sprite* sprite = Sprite::create("Title/title_bg.png");
sprite->setPosition(Point(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
this->addChild(sprite, 0);

//加载火焰纹理
cocos2d::Texture2D* fireTex = CCTextureCache::sharedTextureCache()->addImage("Effect/fire.png");

const int fireCount = 11;
CCParticleSystem* fires[fireCount];

//初始化所有火焰
for (int i = 0; i < fireCount; ++i)
    fires[i] = CCParticleFire::create();

fires[0]->setPosition(Point(100.0f, visibleSize.height - 502.0f));
fires[1]->setPosition(Point(200.0f, visibleSize.height - 563.0f));
fires[2]->setPosition(Point(300.0f, visibleSize.height - 563.0f));
fires[3]->setPosition(Point(400.0f, visibleSize.height - 563.0f));
fires[4]->setPosition(Point(500.0f, visibleSize.height - 563.0f));
fires[5]->setPosition(Point(600.0f, visibleSize.height - 563.0f));
fires[6]->setPosition(Point(700.0f, visibleSize.height - 563.0f));
fires[7]->setPosition(Point(800.0f, visibleSize.height - 563.0f));
fires[8]->setPosition(Point(900.0f, visibleSize.height - 563.0f));
fires[9]->setPosition(Point(1000.0f, visibleSize.height - 563.0f));
fires[10]->setPosition(Point(476.0f, visibleSize.height - 170.0f));

for (int i = 0; i < fireCount; ++i)
{
    fires[i]->setTexture(fireTex);
    fires[i]->setSpeed(100.0f);
    this->addChild(fires[i], 5);
}

//初始化菜单
enum { START_GAME, LOAD_GAME, CREDITS, EXIT, MAX_FLAG };
MenuItemImage* menuItems[MAX_FLAG] =
{
    MenuItemImage::create("Title/newgame_normal.png", "Title/newgame_selected.png", CC_CALLBACK_1(TitleMenu::startGameCallback, this)),
    MenuItemImage::create("Title/loadgame_normal.png", "Title/loadgame_selected.png", CC_CALLBACK_1(TitleMenu::loadGameCallback, this)),
    MenuItemImage::create("Title/credits_normal.png", "Title/credits_selected.png", CC_CALLBACK_1(TitleMenu::creditsCallback, this)),
    MenuItemImage::create("Title/exit_normal.png", "Title/exit_selected.png", CC_CALLBACK_1(TitleMenu::exitGameCallback, this))
};

Menu* menu  = Menu::create();
for (int i = 0; i < MAX_FLAG; ++i)
{
    menuItems[i]->setPosition(Point(0, (((MAX_FLAG - 1)) - i) * 30));
    menu->addChild(menuItems[i]);
}

menu->setPosition(ccp(visibleSize.width / 2 - 90, visibleSize.height / 2 - 50));
this->addChild(menu, 1);

return true;

}

void TitleMenu::startGameCallback(Object* sender)
{

}

void TitleMenu::loadGameCallback(Object* sender)
{

}

void TitleMenu::creditsCallback(Object* sender)
{

}

void TitleMenu::exitGameCallback(Object* sender)
{
Director::getInstance()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);

#endif
}
[/cpp]

具体实现是在有大作风范背景的适当位置加入火焰。火焰特效通过纹理来表现出效果,火焰扭曲运动则通过cocos2d-x的物理引擎计算。如果你觉得很难调整特效的坐标,可以尝试在PhotoShop中打开背景图,然后把画布的尺寸设置为和游戏窗口分辨率一致,通过信息视图就可以看到鼠标指针当前的坐标了。

静态效果图:
ccx_effect_pic

素材与可执行文件下载(已带所需库文件,下载后可直接运行游戏):ccx_title_effect