More Related Content
Similar to ㉔cocos2dでゲームを作ろう!その2 (6)
More from Nishida Kansuke (20)
㉔cocos2dでゲームを作ろう!その2
- 2. 動作環境
• Mac OS X 10.8 Mountain Lion
• xcode 4.5.1
• cocos2d for iPhone 2.0
http://www.cocos2d-iphone.org/
- 4. もくじ
• 前回のおさらい
• MainSceneを作ろう
• カウントダウンを作る
• ゲームスタート
• メインルーチン
• 忍者の動き
• なんでこうするか
• 忍者タッチ!
• TIPS
• まとめ
- 10. メインscene
• フロントlayer
– スコア
– 残機表示
• メインlayer
– カウントダウン、ゲームオーバー
– エフェクト(+1、 )
– 忍者
• 背景layer
– 背景画像
- 11. 音楽素材について①
• 音楽素材については、PANICPUMPKIN様
のご好意により、使用させていただいてい
ます。
• http://panicpumpkin.omiki.com/
• ゲームBGMに特化したサイトなのでおす
すめ!(曲数も多いです)
• 利用報告、 著作表記、リンクなどの明記
不要で商用利用可能の音楽素材を多数公
開されています。
- 14. こんなかんじ
-(id)init{
self = [super init];
if (self) {
self.bgLayer = [CCLayerColor layerWithColor:ccc4(36, 36, 255, 255)];
[self addChild:self.bgLayer z:LAYER_BG tag:LAYER_BG];
GameData *gameData = [GameData getInstance];
gameData.score = 0;
gameData.life = 3;
self.frontLayer = [FrontLayer node];
[self addChild:self.frontLayer z:LAYER_FRONT tag:LAYER_FRONT];
self.mainLayer = [MainLayer node];
[self addChild:self.mainLayer z:LAYER_MAIN tag:LAYER_MAIN];
self.mode = MODE_INIT;
}
return self;
}
- 17. こんなかんじ3
case MODE_PLAY:
if(self.mainLayer.isEndGame){
[[CCDirector sharedDirector] replaceScene:
[CCTransitionFade transitionWithDuration:1.0f scene:
[TitleScene node] withColor:ccc3(0, 0, 0)]];
}
break;
default:
break;
}
[self.frontLayer drawData];
}
- 20. こんなかんじ1
-(void)gameStart{
self.mode =
MAIN_LAYER_MODE_START;
[[SimpleAudioEngine sharedEngine]
stopBackgroundMusic];
[self animeCount4];
}
- 21. こんなかんじ2
-(void)animeCount4{
CCSpriteBatchNode *gameBatchNode =
(CCSpriteBatchNode*)[self getChildByTag:OBJECT_GAME];
[[SimpleAudioEngine sharedEngine] playEffect:@"count.caf"];
CCSprite *sp;
sp = [CCSprite spriteWithSpriteFrameName:@"info.png"];
sp.position = ccp(160, 240);
sp.opacity = 0;
[gameBatchNode addChild:sp z:SPRITE_MAIN_TXT];
- 22. こんなかんじ3
NSMutableArray* actions = [NSMutableArray array];
[actions addObject:[CCFadeIn actionWithDuration:0.4f
* COUNT_RATE]];
[actions addObject:[CCDelayTime actionWithDuration:
2.6f * COUNT_RATE]];
[actions addObject:[CCFadeOut actionWithDuration:
0.4f * COUNT_RATE]];
[actions addObject:[CCCallFuncN actionWithTarget:self
selector:@selector(animeCount3:)]];
id action;
action = [CCSequence actionWithArray:actions];
[sp runAction:action];
}
- 27. こんなかんじ
-(void)gameInit{
self.mode = MAIN_LAYER_MODE_PLAY;
self.ninjaArray = [NSMutableArray array];
GameData *gameData = [GameData
getInstance];
gameData.ninjaMax = 1;
gameData.ninjaSpeed = 0.9f;
[self setLevel];
}
- 29. なんいどのちょうせい
-(void)setLevel{
GameData *gameData = [GameData getInstance];
if(gameData.score > ((gameData.ninjaMax * 5) *
gameData.ninjaMax)){
gameData.ninjaMax++;
}
gameData.ninjaSpeed = 1.0f - (gameData.ninjaMax * 0.05f);
if(gameData.ninjaSpeed < 0.4f){
gameData.ninjaSpeed = 0.4f;
}
}
- 34. こんなかんじ3
-(void)addNinja{
CCSpriteBatchNode *bn =
(CCSpriteBatchNode*)[self
getChildByTag:OBJECT_MAIN];
GameData *gameData = [GameData
getInstance];
for(int i = self.ninjaArray.count; i <
gameData.ninjaMax; ++i){
Ninja *ninja = [[[Ninja alloc]init] autorelease];
ninja.parentLayer = self;
[self.ninjaArray addObject:ninja];
[bn addChild:ninja.sprite z:(i * 100)];
}
}
- 37. 忍者のステータス1
• NINJA_STATUS_INIT
– 忍者の初期表示をおこなう
– standCountを初期化(どれだけ立ってる
か)
– 忍者か偽物かきめる
– 座標を決める
– 登場のアクションを開始
– NINJA_STATUS_MOVEにする
– アクションが終わったら、animeMoveEnd
- 40. 忍者のステータス3
• NINJA_STATUS_STAND
– standCountをデクリメント
– standCountがなくなくなってるか判定
• 正面をむく(にせものはこける)
attackNinjyaEnd
• 消えていくアクション(おわったら、
animeActionEndをよぶ)
• 忍者の場合は、攻撃(親レイヤーの
actionAttackNinjaを呼ぶ)
• NINJA_STATUS_ACTIONにする
- 46. ここまでのまとめ
• メインscene
– フロントlayer
• スコア表示、残機表示
– メインlayer
• カウント表示
• 忍者をうごかす
• ライフがなくなったら、isEndGame=YES
– 背景layer
• 背景画像表示
※メインsceneでは、isEndGameを監視して、
YESになったらタイトル画面にscene遷移
- 47. なんでこうするか
• メインシーンでの処理が簡単になる
– 忍者の数を増やす(配列に入れる)
– 忍者を一人ずつ動かす
– くらったら、ライフを減らす
• 他の動きをするキャラクターの追加が簡
単(Ninjaクラスっぽいのをつくればい
い!)
• もちろん、ほかにも色々方法はあるとお
もう!
- 48. デメリット
• 忍者クラスでの処理と、メインレイヤーで
の処理の切り分けが必要。冗長になった
り、逆にわかりづらくなることも!→
ルールを決めてわかりやすくなる工夫をし
よう!(今回は、スコア表示や 印表示は
忍者クラスにいれないとかのルールで実装
しました。)
- 50. タッチイベントをひろう1
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if(self.mode == MAIN_LAYER_MODE_PLAY){
for(UITouch* touch in touches){
CGPoint touchPoint = [touch locationInView:[touch view]];
touchPoint = [[CCDirector sharedDirector]
convertToGL:touchPoint];
BOOL ret = NO;
for(Ninja *ninja in self.ninjaArray){
if(ninja.type == NINJA_TYPE_NINJA){
ret = [ninja touch:touchPoint];
if(ret){
break;
}
}
}
- 51. タッチイベントをひろう2
if(ret == NO){
for(Ninja *ninja in self.ninjaArray){
if(ninja.type == NINJA_TYPE_DUMMY){
ret = [ninja touch:touchPoint];
if(ret){
break;
}
}
}
}
}
}
}
- 53. touch
• ステータスがNINJA_STATUS_STANDの
場合で、矩形内がタッチされてるか判定
(ほかのステータスの場合は、タッチで
きない)
• 忍者の場合は、スコア+1(親レイヤー
のactionAddScoreを呼ぶ)
• 偽物の場合は、ライフ1(親レイヤーの
actionAttackNinjaを呼ぶ)
- 54. TIPS1
• スプライトの画像を変える
– sf = [[CCSpriteFrameCache sharedSpriteFrameCache]
spriteFrameByName:@"ninTouch_07.png"];
– [self.sprite setDisplayFrame:sf];
- 55. TIPS2
• アニメーションを同時に実行
– [actions addObject:[CCSpawn actions:
– [CCFadeIn actionWithDuration:
0.5f * gameData.ninjaSpeed],
– [CCMoveTo actionWithDuration:
0.5f * gameData.ninjaSpeed position:ccp(x, y)],
– nil]];