読者です 読者をやめる 読者になる 読者になる

夏までにiPhone アプリつくってみっか!

趣味でiPhone/Androidアプリを開発し、日々勉強した事を書いています。オープンワールド系レースゲームをUnityで開発中です。

【SpriteKit】Sprite Kit vs cocos2d パフォーマンス対決 (続編) バッチノードでばっちり?

SpriteKit cocos2d

前回の、「Sprite Kit vs cocos2d パフォーマンス対決! 意外にも?」の続編になります。

Sprite Kitに関しましてはAppleのオフィシャルドキュメント「Sprite Kit Programming Guide」が現状唯一の解説書になりますので、ひたすら読んでいるところです。

(Getting StartedでSpriteKitフレームワークをプロジェクトに追加する部分ではAdd Files toメニューで追加するという説明がポップアップウィンドウで表示されますが何のファイルをAddすればいいかわかりません。
私はプロジェクトのTARGETSのGeneralタブの中のLinked Frameworks and Librariesのなかの”+”ボタンを押してSpriteKit.frameworkを追加する方法で追加しました。)

「Jumping into Sprite Kit」という章では実際にコードを入力しながら動作を確認できるように作られています。その中でDraw Callの回数の表示方法を見つけました。

spriteView.showsDrawCount = YES;

の部分です。前回のSprite Kitプロジェクトにこれを追加して実行してみます。

ポチポチと画面をタップして行きます。

f:id:takujidev:20131021193934j:plain:w300

ノードカウントは上がって行きますが、ドローカウントは上がって行きません。
つまり、バッチ処理されています
私の予想は見事に裏切られました。
昨日の対決はcocos2dはバッチ処理なし、Sprite Kitはバッチ処理ありの比較となっていました。
これはフェアではありません。

ならばcocos2dでバッチ処理をした場合はどうなんだと早速SpriteBatchNodeを使うようにプログラムを修正します。

@implementation HelloWorldLayer {
    CCSpriteBatchNode* batchNode;
}

-(id) init
{
	// always call "super" init
	// Apple recommends to re-assign "self" with the "super's" return value
	if( (self=[super init]) ) {
        
        
		
		// create and initialize a Label
		CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello, World!" fontName:@"Chalkduster" fontSize:30];

		// ask director for the window size
		CGSize size = [[CCDirector sharedDirector] winSize];
	
		// position the label on the center of the screen
		label.position =  ccp( size.width /2 , size.height/2 );
		
		// add the label as a child to this Layer
		[self addChild: label];
        
        self.isTouchEnabled = YES;
        
        batchNode = [CCSpriteBatchNode batchNodeWithFile:@"Spaceship.png"];
        [self addChild:batchNode];
        
	}
	return self;
}

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches) {
        CGPoint location = [touch locationInView:touch.view];
        location = [[CCDirector sharedDirector] convertToGL:location];
        
        CCSprite *sprite = [CCSprite spriteWithFile:@"Spaceship.png"];
        
        sprite.position = location;
        
        id action = [CCRotateBy actionWithDuration:1 angle:180];
        
        [sprite runAction:[CCRepeatForever actionWithAction:action]];
        
        [batchNode addChild:sprite];
    }
}

@end

バッチノードを使う場合はドロー数とノード数が一致しないので、ノード数が表示されないcocos2dではタップの回数で宇宙船の数を数えて行きます。

f:id:takujidev:20131021200149j:plain:w300

70機で60fpsの維持が不可能になりました。

Sprite Kitは67機でしたので、何とcocos2dが再逆転してしまいました。

納得いかないのはバッチノードを使わない場合と比較して5機分のパフォーマンス向上しか見られなかった事です。つまりたった7.7%です。

結論。
実用上はスプライトバッチノードは思ったより高速化に貢献しないかもしれないです。