2012年8月アーカイブ

こんにちは。開発担当のICTFです。

右に行ける時は右矢印、左に行ける時は左矢印といった具合に、状況によって表示するイメージを変えたいといったことは無いでしょうか。
同じ座標に2枚のCCSpriteを重ね、表示・非表示を切換える方法が楽ではありますが、フレームレートの保持やメモリがギリギリの時など少しでも節約したい場合には控えたい方法ですね。

今回は、1つのCCSpriteオブジェクト内で複数のテクスチャを表示する為の方法を紹介しようと思います。
紹介といっても、している事はCCSpriteの初期化処理と大差ありません。

まずは普通にCCSpriteオブジェクトを生成します。

CCSprite* sprite = [CCSprite spriteWithFile:@"image1.png"];


このspriteオブジェクトに表示するイメージを「image2.png」に変更するには、次の手順を記述します。

CCTexture2D* tex = [[CCTextureCache sharedTextureCache] addImage:@"image2.png"];

[sprite setTexture:tex];

CGRect rect = CGRectMake(0, 0, sprite.contentSize.widthsprite.contentSize.height);

[sprite setTextureRect:rect];


setTextureメソッドのみだとテクスチャの切換えが行なわれませんので、忘れずsetTextureRectメソッドもコールするようにしてください。
こんにちは。開発担当のICTFです。

今回は久しぶりにcocos2dの話題です。
CCSpriteなどにタッチイベントを持たせたい場合、CCTouchDispatcherを用いますね。
CCTouchDispatcherは非常に便利なクラスですが、ディスパッチャからオブジェクトを削除するタイミングを違えるとメモリリークの原因ともなります。

CCTouchDispatcherへの登録は、対象となるクラスがオブジェクトとして成立してから行なう必要があります。
init()内で登録を行なっても、正常にタッチイベントを受け取る事ができません。
オブジェクトとして成立した直後にフレームワークからコールされるメソッドとしてonEnter()というものがありますので、その中でCCTouchDispatcherへの登録を行なう必要があります。

またCCTouchDispatcherからの削除もdealloc()内で行なうと正しくタッチイベントの登録を解除する事ができません。
例えばボタンのイメージを表示しているCCSpriteをCCTouchDispatcherに登録しているとします。
そのCCSpriteのdealloc()内でCCTouchDispatcherからの削除処理を記述しているとした場合、どのようになるでしょうか。
dealloc()が呼ばれるのは、CCSpriteが親ノードからremoveされるタイミングです。
一見ボタンは画面から消えたように見えますが、CCTouchDispatcherからの削除とCCSpriteの解放処理が正しく行なわれずに、透明なオブジェクトが相変わらず画面上に存在する様なイメージになります。
ボタンは見えないのにタッチイベントだけはブロックされてしまい、なぜか思うようにタッチイベントの受信ができなくなるのです。
この問題を起こさない為に、dealloc()内でCCTouchDispatcherからの削除処理を記述するのではなく、dealloc()前にフレームワークからコールされるonExit()内で記述するようにします。

特にCCTouchDispatcherからの解放ミスについては、アプリが落ちやすくなるだけでなく、タッチイベントが異常動作をするという非常に分かり辛い現象となってしまいますので注意が必要です。
こんにちは。開発担当のICTFです。

今回はUIColorクラスに設定されている色をUserDefaultに保存する為の方法を紹介します。
一番簡単な方法としては、

[[NSUserDefaults standardUserDefaults] setObject:[UIColor whiteColor] forKey:@"Color"];

このようにsetObject:で保存し、

UIColor* color = [[NSUserDefaults standardUserDefaults] objectForKey:@"Color"];

objectForKey:で読み込むことですね。

勿論この方法で問題が無ければ、簡単ですし一番お勧めできる方法です。


しかし、上記の記録方法を採った場合plistなどに初期値の色を設定できないところが難点です。

ですので初期値としての色をplistに設定でき、かつUIColorとしてシームレスに使うことのできる実装を行ないます。


流れとしては、

1. UIColorのRGB成分をそれぞれFloat型変数に抽出する

2. 3つ(R, G, B)のFloat変数をUserDefaultに保存する

3. UserDefaultから3つの値を読み込み、UIColorを生成する

となります。


それでは1から順に実装していきましょう。

-(void) setColor:(UIColor *)Color

{

[_Color release];

_Color = [Color retain];

// ユーザデフォルトに書き込む

const CGFloat* c = CGColorGetComponents(_Color.CGColor);

NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];

[defaults setFloat:c[0] forKey:COLOR_R];

[defaults setFloat:c[1] forKey:COLOR_G];

[defaults setFloat:c[2] forKey:COLOR_B];

[defaults synchronize];

}

例ではUIColor型プロパティのセッターに実装しています。

CGColorGetComponents関数にCGColorを渡すことにより、各要素がCGFloat型の配列で返されます。

配列の引数と値の対応は以下の通りです。

[0]:赤(R)

[1]:緑(G)

[2]:青(B)

[3]:Alpha

各要素をsetFloat:で保存します。


読み込みは次のように実装します。

self.Color = [UIColor colorWithRed:[defaults floatForKey:COLOR_R] green:[defaults floatForKey:COLOR_G] blue:[defaults floatForKey:COLOR_B] alpha:1.0];


最後にplistに3つの値の初期値を設定すれば実装完了となります。