cocos2d を使ったときの CCSprite の後始末のしかたのメモです。

CCSpriteSheet から CCSprite を作ったときの破棄と CCAnimation が終わったタイミングでの CCSprite の破棄の方法をメモしています。

CCSpriteSheet から作ったスプライトの後処理

CCSpriteSheet から CCSprite を作成する場合、次のように書きます。

CCSpriteSheet *sheet = [CCSpriteSheet spriteSheetWithFile:@"missile.png"];
[self addChild:sheet];
  
CCSprite *missile = [CCSprite spriteWithSpriteSheet:sheet rect:CGRectMake(0, 0, 32, 32)];
[sheet addChild:missile];

このように、CCSpriteSheet から CCSprite を作成した場合、CCLayer(self) にはスプライトシートのオブジェクトを追加して、スプライトはスプライトシートに追加する形で記述します。

こうすると、スプライトが必要なくなってスプライトを破棄したくなった場合に、スプライトシートから取り除く必要があります。

この時 スプライトシートの removeChild:cleanup: メソッドでは上手くいきません。

それではどうするかというと、スプライトの方の removeFromParentAndCleanup: メソッドを使います。

[sprite removeFromParentAndCleanup:YES];

CCAction や CCAnimation が終わったタイミングでのスプライトの後処理

スプライトにアクションやアニメーションを付ける場合は、CCAction や CCAnimation を使います。

そして、アクションやアニメーションが終了したタイミングでスプライトを削除したい場合には、アクションの最後で CCCallFuncND を使って removeFromParentAndCleanup: メソッドを呼び出すようにします。(19行目)

次に例を載せておきます。この例は、ミサイルが爆発したときの爆発をアニメーションで表したものです。CCAnimation を使うので、burst.plist を別途記述して、アニメーションの定義をしています。コード例のあとに載せてあるのがそうです。

また、burst.png は 8×8 の爆発を表現する画像が9つ並んだものになっています。

burst.m

// アニメーションの定義(個別のスプライトの定義)をスプライトキャッシュに登録して、後で呼び出せるようにする
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"burst.plist"];
 
// アニメーション定義と対応するスプライトの画像を読み込む 
CCSpriteSheet *sheet = [CCSpriteSheet spriteSheetWithFile:@"burst.png"];
[self addChild:sheet];
 
// アニメーションの最初のスプライトを読み込む  
CCSprite *sprite = [CCSprite spriteWithSpriteFrameName:@"burst01"];
sprite.position = ccp(160, 240);
[sheet addChild:sprite];
 
// アニメーションのコマに対応するスプライトをフレームとして作成する  
NSMutableArray *animFrames = [NSMutableArray array];
for (int i = 2; i <= 9; i++) {
  CCSpriteFrame *frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"burst%02d", i]];
  [animFrames addObject:frame];
}
 
// アニメーションフレームをアニメーションにしてスプライトと紐付ける
// アニメーションの最後に removeFromParentAndCleanup: を呼び出してスプライトを破棄する
CCAnimation *animation = [CCAnimation animationWithName:@"burst" delay:0.2f frames:animFrames];
[sprite runAction:[CCSequence actions:
                   [CCAnimate actionWithAnimation:animation restoreOriginalFrame:NO],
                   [CCCallFuncND actionWithTarget:sprite selector:@selector(removeFromParentAndCleanup:) data:(void *)YES],
                   nil]];

burst.png

missile.png

burst.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>texture</key>
  <dict>
    <key>width</key>
    <integer>72</integer>
    <key>height</key>
    <integer>8</integer>
  </dict>
  <key>frames</key>
  <dict>
    <key>burst01</key>
    <dict>
      <key>x</key>
      <integer>0</integer>
      <key>y</key>
      <integer>0</integer>
      <key>width</key>
      <integer>8</integer>
      <key>height</key>
      <integer>8</integer>
      <key>originalWidth</key>
      <integer>8</integer>
      <key>originalHeight</key>
      <integer>8</integer>
    </dict>
    <key>burst02</key>
    <dict>
      <key>x</key>
      <integer>8</integer>
      <key>y</key>
      <integer>0</integer>
      <key>width</key>
      <integer>8</integer>
      <key>height</key>
      <integer>8</integer>
      <key>originalWidth</key>
      <integer>8</integer>
      <key>originalHeight</key>
      <integer>8</integer>
    </dict>
    <key>burst03</key>
    <dict>
      <key>x</key>
      <integer>16</integer>
      <key>y</key>
      <integer>0</integer>
      <key>width</key>
      <integer>8</integer>
      <key>height</key>
      <integer>8</integer>
      <key>originalWidth</key>
      <integer>8</integer>
      <key>originalHeight</key>
      <integer>8</integer>
    </dict>
    <key>burst04</key>
    <dict>
      <key>x</key>
      <integer>24</integer>
      <key>y</key>
      <integer>0</integer>
      <key>width</key>
      <integer>8</integer>
      <key>height</key>
      <integer>8</integer>
      <key>originalWidth</key>
      <integer>8</integer>
      <key>originalHeight</key>
      <integer>8</integer>
    </dict>
    <key>burst05</key>
    <dict>
      <key>x</key>
      <integer>32</integer>
      <key>y</key>
      <integer>0</integer>
      <key>width</key>
      <integer>8</integer>
      <key>height</key>
      <integer>8</integer>
      <key>originalWidth</key>
      <integer>8</integer>
      <key>originalHeight</key>
      <integer>8</integer>
    </dict>
    <key>burst06</key>
    <dict>
      <key>x</key>
      <integer>40</integer>
      <key>y</key>
      <integer>0</integer>
      <key>width</key>
      <integer>8</integer>
      <key>height</key>
      <integer>8</integer>
      <key>originalWidth</key>
      <integer>8</integer>
      <key>originalHeight</key>
      <integer>8</integer>
    </dict>
    <key>burst07</key>
    <dict>
      <key>x</key>
      <integer>48</integer>
      <key>y</key>
      <integer>0</integer>
      <key>width</key>
      <integer>8</integer>
      <key>height</key>
      <integer>8</integer>
      <key>originalWidth</key>
      <integer>8</integer>
      <key>originalHeight</key>
      <integer>8</integer>
    </dict>
    <key>burst08</key>
    <dict>
      <key>x</key>
      <integer>56</integer>
      <key>y</key>
      <integer>0</integer>
      <key>width</key>
      <integer>8</integer>
      <key>height</key>
      <integer>8</integer>
      <key>originalWidth</key>
      <integer>8</integer>
      <key>originalHeight</key>
      <integer>8</integer>
    </dict>
    <key>burst09</key>
    <dict>
      <key>x</key>
      <integer>64</integer>
      <key>y</key>
      <integer>0</integer>
      <key>width</key>
      <integer>8</integer>
      <key>height</key>
      <integer>8</integer>
      <key>originalWidth</key>
      <integer>8</integer>
      <key>originalHeight</key>
      <integer>8</integer>
    </dict>
  </dict>
</dict>
</plist>