Cocos2d-x 3.x で音楽をフェードアウト・フェードインさせる
Cocos2d-x 標準の SimpleAudioEngine はあまりにもシンプルすぎて音楽のフェードにすら対応していない。これを解決しようという試みが Music Fader for Cocos2dx でなされているが、このコードはバージョンが古く、おそらく 3.x 系で追加されたのであろう pure virtual な関数が実装されていないため、このままでは使用できない。この点を改善したコードを書いたので載せる。自由に使っていただいて構わない。
使い方
Node に対する Action として用いる。たとえば Scene に直接つけちゃおう(適当)。
nodeInstance->runAction(MusicFade::create(1.0f, 0.0f, true));
MusicFade.h
// This code is originally from http://www.fuguelike.com/music-fader-for-cocos2dx/ // but altered to make it work with Cocos2d-x 3.x #ifndef __MusicFade__ #define __MusicFade__ #include "cocos2d.h" #include "nmd.h" class MusicFade : public cocos2d::ActionInterval { public: MusicFade(); static MusicFade* create(float d, float volume, bool pauseOnComplete = false ); bool initWithDuration(float d, float volume, bool pauseOnComplete ); virtual MusicFade* clone() const override; // pure virtual virtual MusicFade* reverse() const override; // pure virtual virtual void startWithTarget(cocos2d::Node *pTarget); virtual void update(float time); virtual void stop(void); protected: float m_targetVal; float m_initialVal; bool m_bPauseOnComplete; }; #endif /* defined(__MusicFade__) */
MusicFade.cpp
#include "MusicFade.h" #include "SimpleAudioEngine.h" using namespace cocos2d; using namespace CocosDenshion; MusicFade::MusicFade() { m_initialVal = 0; m_targetVal = 0; } MusicFade* MusicFade::create(float duration, float volume, bool pauseOnComplete) { MusicFade *pAction = new MusicFade(); pAction->initWithDuration(duration, volume, pauseOnComplete); pAction->autorelease(); return pAction; } bool MusicFade::initWithDuration(float duration, float volume, bool pauseOnComplete) { if (CCActionInterval::initWithDuration(duration)) { m_targetVal = volume; m_bPauseOnComplete = pauseOnComplete; return true; } return false; } void MusicFade::update(float time) { float vol = m_initialVal + time*(m_targetVal - m_initialVal); SimpleAudioEngine::getInstance()->setBackgroundMusicVolume(vol); } MusicFade* MusicFade::clone(void) const { // no copy constructor auto a = new MusicFade(); a->initWithDuration(_duration, m_targetVal, m_bPauseOnComplete); a->autorelease(); return a; } MusicFade* MusicFade::reverse() const { return MusicFade::create(_duration, m_targetVal); } void MusicFade::startWithTarget(Node *pTarget) { CCActionInterval::startWithTarget( pTarget ); m_initialVal = SimpleAudioEngine::getInstance()->getBackgroundMusicVolume(); } void MusicFade::stop(void) { if(m_bPauseOnComplete) SimpleAudioEngine::getInstance()->pauseBackgroundMusic(); CCActionInterval::stop(); }