六、音乐音效的实现
- Wenderlic文章中提供的这两个音乐文件,是caf格式,这是苹果自己的格式。我们在这里分别转成WAV和MP3,演示一下SimpleAudioEngine对这两种大众格式的支持
- 和前面的图片资源一样,我们先简单化地把音乐资源拷贝到uphone模拟器默认的资源目录下,通过直接读文件来使用。在本系列教程的下一篇“打包发布”中将会描述如何把图片和音乐和程序打在一个二进制包里,游戏开发者不用担心资源被人轻易拷走后山寨的问题
先在HelloWorldScene.cpp的开头,添加对SimpleaudioEngine.h的包含
//
cpp with cocos2d-x
#include " SimpleAudioEngine/SimpleAudioEngine.h " |
//
objc with cocos2d-iphone
#import " SimpleAudioEngine.h " |
然后在bool HelloWorld::init()方法中,加入播放背景音乐的代码
//
cpp with cocos2d-x
SimpleAudioEngine::getSharedEngine() -> playBackgroundMusic( "background-music-aac.mp3"); |
//
objc with cocos2d-iphone
[[SimpleAudioEngine sharedEngine] playBackgroundMusic: @"background-music-aac.caf"]; |
接着在ccTouchesEnded方法中播放扔出飞镖的音效
//
cpp with cocos2d-x
SimpleAudioEngine::getSharedEngine() -> playEffect( " pew-pew-lei.wav " ); |
//
objc with cocos2d-iphone
[[SimpleAudioEngine sharedEngine] playEffect: @" pew-pew-lei.caf " ]; |
音效和背景音乐就这样简单搞定了。
七、最后的润色
现在让我们创建一个新场景,在打掉若干小怪、或者被小怪穿到屏幕左边时显示“You Win”或“You Lose”的界面。在Visual Studio中新建两个文件, GameOverScene.cpp和GameOverScene.h
GameOverScene.h的内容
1
//
cpp with cocos2d-x
2 #ifndef _GAME_OVER_SCENE_H_ 3 #define _GAME_OVER_SCENE_H_ 4 5 #include " cocos2d.h " 6 7 class GameOverLayer : public cocos2d::CCColorLayer 8 { 9 public : 10 GameOverLayer():_label(NULL) {}; 11 virtual ~ GameOverLayer(); 12 bool init(); 13 LAYER_NODE_FUNC(GameOverLayer); 14 15 void gameOverDone(); 16 17 CCX_SYNTHESIZE_READONLY(cocos2d::CCLabel * , _label, Label); 18 }; 19 20 21 22 23 24 class GameOverScene : public cocos2d::CCScene 25 { 26 public : 27 GameOverScene():_layer(NULL) {}; 28 ~ GameOverScene(); 29 bool init(); 30 SCENE_NODE_FUNC(GameOverScene); 31 32 CCX_SYNTHESIZE_READONLY(GameOverLayer * , _layer, Layer); 33 }; 34 35 36 37 #endif // _GAME_OVER_SCENE_H_ |
1
//
objc with cocos2d-iphone
2 3 4 5 #import " cocos2d.h " 6 7 @interface GameOverLayer : CCColorLayer 8 { 9 10 11 12 13 14 15 16 17 CCLabel * _label; 18 } 19 20 @property (nonatomic, retain) CCLabel * label; 21 22 @end 23 24 @interface GameOverScene : CCScene 25 { 26 27 28 29 30 31 32 GameOverLayer * _layer; 33 } 34 35 @property (nonatomic, retain) GameOverLayer * layer; 36 37 @end |
接着就实现GameOverScene.cpp的内容
1
//
cpp with cocos2d-x
2 #include " GameOverScene.h " 3 #include " HelloWorldScene.h " 4 5 using namespace cocos2d; 6 7 8 bool GameOverScene::init() 9 { 10 if ( CCScene::init() ) 11 { 12 this -> _layer = GameOverLayer::node(); 13 _layer -> retain(); 14 this -> addChild(_layer); 15 16 return true ; 17 } 18 else 19 { 20 return false ; 21 } 22 } 23 24 GameOverScene:: ~ GameOverScene() 25 { 26 if (_layer) 27 { 28 _layer -> release(); 29 _layer = NULL; 30 } 31 } 32 33 34 35 36 37 38 bool GameOverLayer::init() 39 { 40 if ( CCColorLayer::initWithColor( ccc4( 255 , 255 , 255 , 255 ) ) ) 41 { 42 CGSize winSize = CCDirector::getSharedDirector() -> getWinSize(); 43 this -> _label = CCLabel::labelWithString( "" , " Artial " , 32 ); 44 _label -> retain(); 45 _label -> setColor( ccc3( 0 , 0 , 0 ) ); 46 _label -> setPosition( ccp(winSize.width / 2 , winSize.height / 2 ) ); 47 this -> addChild(_label); 48 49 this -> runAction( CCSequence::actions( 50 CCDelayTime::actionWithDuration( 3 ), 51 CCCallFunc::actionWithTarget( this , 52 callfunc_selector(GameOverLayer::gameOverDone)), 53 NULL)); 54 55 return true ; 56 } 57 else 58 { 59 return false ; 60 } 61 } 62 63 void GameOverLayer::gameOverDone() 64 { 65 CCDirector::getSharedDirector() -> replaceScene( HelloWorld::scene() ); 66 } 67 68 GameOverLayer:: ~ GameOverLayer() 69 { 70 if (_label) 71 { 72 _label -> release(); 73 _label = NULL; 74 } 75 } 76 77 |
1
//
objc with cocos2d-iphone
2 #import " GameOverScene.h " 3 #import " HelloWorldScene.h " 4 5 @implementation GameOverScene 6 @synthesize layer = _layer; 7 8 - (id)init 9 { 10 if ((self = [super init])) 11 { 12 self.layer = [GameOverLayer node]; 13 14 [self addChild:_layer]; 15 } 16 return self; 17 } 18 19 20 21 22 23 24 - ( void )dealloc 25 { 26 27 28 [_layer release]; 29 _layer = nil; 30 [super dealloc]; 31 } 32 33 @end 34 35 @implementation GameOverLayer 36 @synthesize label = _label; 37 38 - (id) init 39 { 40 if ( (self = [super initWithColor:ccc4( 255 , 255 , 255 , 255 )] )) 41 { 42 CGSize winSize = [[CCDirector sharedDirector] winSize]; 43 self.label = [CCLabel labelWithString: @"" fontName: @" Arial " fontSize: 32 ]; 44 45 _label.color = ccc3( 0 , 0 , 0 ); 46 _label.position = ccp(winSize.width / 2 , winSize.height / 2 ); 47 [self addChild:_label]; 48 49 [self runAction:[CCSequence actions: 50 [CCDelayTime actionWithDuration: 3 ], 51 [CCCallFunc actionWithTarget:self 52 selector:@selector(gameOverDone)], 53 nil]]; 54 } 55 return self; 56 } 57 58 59 60 61 62 63 - ( void )gameOverDone 64 { 65 [[CCDirector sharedDirector] replaceScene:[HelloWorld scene]]; 66 } 67 68 - ( void )dealloc 69 { 70 71 72 [_label release]; 73 _label = nil; 74 [super dealloc]; 75 } 76 77 @end |
注意,上面GameOverScene.cpp里有两个对象,一个场景(scene)和一个图层(layer),场景可以包含多个图层,而这个图层只在屏幕正中间放了一个文字标签(label),显示3秒种后返回到HelloWorldScene中。
最后,为了调用起这个GameOverScene,我们需要在HelloWorldScene中添加一些游戏逻辑代码。先得添加一个变量,判断我们的带头大哥一共用飞镖干掉了多少杂兵。在class HelloWorld中添加一个成员变量:
1
//
cpp with cocos2d-x
2 protected : 3 int _projectilesDestroyed; |
1
//
objc with cocos2d-iphone
2 3 int _projectilesDestroyed; |
然后在HelloWorldScene.cpp中,添加对GameOverScene.h的引用
//
cpp with cocos2d-x
#include " GameOverScene.h " |
//
objc with cocos2d-iphone
#import " GameOverScene.h " |
在HelloWorld::update方法中的removeChild(target)后面的targetsToDelete循环中增加计数并检查获胜条件,获胜了就显示"You Win!"界面
//
cpp with cocos2d-x
_projectilesDestroyed ++ ; if (_projectilesDestroyed > 30 ) { GameOverScene * gameOverScene = GameOverScene::node(); gameOverScene -> getLayer() -> getLabel() -> setString( " You Win! " ); CCDirector::getSharedDirector() -> replaceScene(gameOverScene); } |
//
objc with cocos2d-iphone
_projectilesDestroyed ++ ; if (_projectilesDestroyed > 30 ) { GameOverScene * gameOverScene = [GameOverScene node]; [gameOverScene.layer.label setString: @" You Win! " ]; [[CCDirector sharedDirector] replaceScene:gameOverScene]; } |
与之匹配的是失败条件:任何一个反派小兵穿越了屏幕的最左边,你就挂了。于是修改spriteMoveFinished方法,在if (sprite->getTag() == 1)条件里面增加“You Lose”的代码:
//
cpp with cocos2d-x
GameOverScene * gameOverScene = GameOverScene::node(); gameOverScene -> getLayer() -> getLabel() -> setString( " You Lose :[ " ); CCDirector::getSharedDirector() -> replaceScene(gameOverScene); |
//
objc with cocos2d-iphone
GameOverScene * gameOverScene = [GameOverScene node]; [gameOverScene.layer.label setString: @" You Lose :[ " ]; [[CCDirector sharedDirector] replaceScene:gameOverScene]; |
最后编译并运行整个游戏项目,这样你就可以听到带头大哥扔飞镖同时很嚣张地发出的DIU~DIU~的声音,还有很HIGH的背景音乐循环播放;另一方面,游戏赢或输了会有一个界面提示。
这个游戏至此,已经在模拟器上100%完成了。下一篇我们讲如何做交叉编译成linux版本(也就是Uphone真机运行的版本), 如何打包图片和音乐资源到程序二进制中防止被拷贝、以及如何用制作成Uphone安装包发布。
本文转自Walzer博客园博客,原文链接:http://www.cnblogs.com/walzer/archive/2010/10/12/1849063.html,如需转载请自行联系原作者