Cocos2d-x游戏开发实例详解2:开始菜单续

2015年03月25日 13:32 0 点赞 0 评论 更新于 2017-05-05 05:32

本系列通过实际演练,详细解说Cocos2d-x引擎的各个模块。上一篇文章已经实现了MoonWarriors开始菜单的大部分元素,还差一个运动的飞船、一个点击newGame的特效和音效未实现,下面将详细介绍这些功能的实现。

1. 飞船

飞船的创建与基本设置

以下是创建飞船的代码:

// ships
CCTexture2D *textCache = CCTextureCache::sharedTextureCache()->addImage(s_ship01);
m_ship = CCSprite::createWithTexture(textCache, CCRectMake(0, 45, 60, 38));
this->addChild(m_ship, 0, 4);
CCPoint position = ccp(CCRANDOM_0_1() * winSize.width, 0);
m_ship->setPosition(position);
m_ship->runAction(CCMoveBy::create(2, ccp(CCRANDOM_0_1() * winSize.width, position.y + winSize.height + 100)));

这里创建的飞船是一个简单的CCSprite对象。后续会创建一个飞船类,但目前仅使用CCSprite。代码的主要步骤为:首先缓存飞船图片,接着创建飞船对象,将其添加到当前节点,设置飞船的初始位置,最后执行移动动作。

在设置飞船位置时,使用了CCRANDOM_0_1()函数,该函数是Cocos2d-x引擎封装的随机函数,用于生成一个0到1之间的float类型随机数,从而使每次飞船出现的位置具有随机性。同样,移动的目标点也有一定的随机性,通过CCMoveBy动作实现飞船的移动。

让飞船持续飞行

需要注意的是,上述代码都在init()函数中完成,即使执行了runAction,飞船的移动动作也仅会执行一次。为了实现不断有飞船在屏幕上飞行的效果,需要使用schedule()函数进行任务调度。该函数会每隔指定的时间dt调用一次回调函数,这里设置为每0.1秒执行一次update函数:

this->schedule(schedule_selector(StartMenu::update), 0.1);

以下是update函数的实现:

if (m_ship->getPosition().y > 480) {
CCPoint pos = ccp(CCRANDOM_0_1() * winSize.width, 10);
m_ship->setPosition(pos);
m_ship->runAction(CCMoveBy::create(floor(5 * CCRANDOM_0_1()), ccp(CCRANDOM_0_1() * winSize.width, pos.y + 480)));
}

当飞船飞出屏幕(y坐标大于480)后,会重新设置其位置并执行新的移动动作。

2. 音效

音效的实现非常简单,直接使用了Cocos2d-x的声音引擎:

SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(0.7);
SimpleAudioEngine::sharedEngine()->playBackgroundMusic(s_mainMainMusic, true);

上述代码设置了背景音乐的音量为0.7,并循环播放指定的背景音乐。

3. 点击特效

在HTML5版中,点击特效可以通过一个匿名函数轻松实现,但在Cocos2d-x中,为了实现点击特效,创建了一个特效类。

记得前面有个flareEffect函数,就是在这里处理点击特效的:

void StartMenu::flareEffect(CCNode *node)
{
onButtonEffect();
Effect* flareEffect = Effect::create();
CCCallFunc *callback =  CCCallFunc::create(this, callfunc_selector(StartMenu::newGame));
flareEffect->flareEffect(this, callback);
}

onButtonEffect是声音特效函数,Effect类用于实现动画特效,关键在于其flareEffect函数。以下是Effect::flareEffect函数的实现:

void Effect::flareEffect(CCNode *parent, CCCallFunc *callback)
{
// 特效图片
CCSprite *flare = CCSprite::create(s_flare);

// 设置混合模式
ccBlendFunc cbl = {GL_SRC_ALPHA, GL_ONE};
flare->setBlendFunc(cbl);

// 添加到父节点
parent->addChild(flare, 10);

// 设置初始透明度
flare->setOpacity(0);

// 设置初始位置
flare->setPosition(ccp(-30, 297));

// 设置初始角度
flare->setRotation(-120);

// 设置初始放大系数
flare->setScale(0.2);

// 透明度渐变
CCActionInterval *opacityAnim = CCFadeTo::create(0.5, 255);
CCActionInterval *opacDim = CCFadeTo::create(1, 0);

// 大小渐变
CCActionInterval *bigAnim = CCScaleBy::create(0.7, 1.2, 1.2);

// 渐变速率,正玄变化,由快到慢
CCEaseSineOut *biggerEase = CCEaseSineOut::create(bigAnim);
CCActionInterval *moveAnim = CCMoveBy::create(0.5, ccp(328, 0));
CCEaseSineOut *moveEase = CCEaseSineOut::create(moveAnim);

// 角度旋转
CCActionInterval *roteAnim = CCRotateBy::create(2.5, 90);

// 角度旋转速度,指数变化
CCEaseExponentialOut * rotateEase = CCEaseExponentialOut::create(roteAnim);

// 放大到原大小
CCScaleTo *bigger = CCScaleTo::create(0.5, 1);

// 动画完成后回调函数
CCCallFuncN *onComplete =  CCCallFuncN::create(flare, callfuncN_selector(Effect::killFlare));

// 执行动画和回调函数
flare->runAction(CCSequence::create(opacityAnim, biggerEase, opacDim, onComplete, callback,  NULL));
flare->runAction(moveEase);
flare->runAction(rotateEase);
flare->runAction(bigger);
}

该函数的主要步骤为:创建特效精灵对象,设置其混合模式、初始透明度、位置、角度和放大系数,然后创建各种动画动作,如透明度渐变、大小渐变、位置移动和角度旋转等,最后将这些动作组合并执行。动画完成后,会调用killFlare函数,该函数用于移除特效精灵,避免其一直存在。

到这里,开始菜单的基本功能就已实现,不过还缺少一些回调和状态控制等功能,后续会继续完善。

作者信息

boke

boke

共发布了 1025 篇文章