だいたい47度

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

PageTop

CCMenuItemに簡単にtoggle機能を付加

cocos2d-extensionのCCAdvancedMenuにおいて、CCMenuItemSpriteに「選択すると選択された状態画像が維持され、同menu内の他のボタンが押されたときに非選択状態画像に変わる」機能を付けたいと思いました。結果的にCCMenuでも使えるものになっているのと、単純な話なのに混乱して2-3時間悩んだので、メモがてら公開。

CCMenuItemToggleに、normalImageとselectedImageを良い感じにしたCCMenuItemSpriteを付加する方法もありますが、すでにあるボタンに関して書き換える量が多いので、CCMenuItemSpriteを上書きすることで実装しました。

まずメソッドtoggleとuntoggleを実装します。それぞれのvisibleを書き換えてやるだけの処理です。toggle状態をisToggledで管理します。

//CCMenuItemSpriteToggle.m
@implementation CCMenuItemSpriteToggle{
BOOL _isToggled;
}

- (void)toggle{
_isToggled = YES;
[normalImage_ setVisible:NO];
[selectedImage_ setVisible:YES];
[disabledImage_ setVisible:NO];
}
- (void)untoggle{
_isToggled = NO;
[normalImage_ setVisible:YES];
[selectedImage_ setVisible:NO];
[disabledImage_ setVisible:NO];
}
//続く


あとはこれらのメソッドを呼び出す箇所を決めます。

まずはtoggleの呼び出し箇所を考えます。

CCAdvancedMenuのタッチ開始時と終了時の処理はCCMenuと同じです。タッチ開始時にCCMenuItemのselectedを呼び出し、指を離すとunselected→activateの順で呼び出します。selectedではnormalImageのvisibleをNOにし、selectedImageのvisibleをYESにします(toggleと同じ描画)。unselectedではその逆の動作を行います(untoggleと同じ描画)。activateは設定した関数を呼び出します。

よって、activate内でtoggleを呼び出せばよいように思いますが、それだけではダメです。CCAdvancedMenuでは、ある程度以上の距離をドラッグすると、ccTouchMovedメソッドの中でunselectedが呼び出されるようになっているのです。そのため、toggleされているボタンをタッチしてドラッグ操作をするとunselectedが呼ばれ、描画が元に戻ってしまいます。

以上のことからunselectedを上書きする必要があります。単純に無効化するだけでは、ccTouchCancelledのunselectedも効かなくなり、toggleされていないボタンからドラッグを開始した際にselectedされたままになってしまうので、以下のようにオーバーライドします。これでtoggle側の呼び出しはおしまいです。

//続き
- (void)activate{
[self toggle];
[super activate];
}

- (void)unselected{
[super unselected];
if (_isToggled) { [self toggle]; }
}
@end


次にuntoggleの呼び出し箇所を考えます。

untoggleは同じmenu内の他のボタンが押された場合に呼び出されるべきなので、CCMenuItemSpriteToggleの外から呼び出します。現在toggleされているボタンを認識できるようにしておき、menu各ボタンが押された時にtoggleされているボタンのuntoggleを呼び出せばOKです。


以上、後は普通のCCMenuItemSpriteと同じように使えます。CCMenuItem自体に実装すればもっと広範に使える気もします。更にCCMenuのサブクラスも作ったりもできそうです。
関連記事
スポンサーサイト

PageTop

コメント


管理者にだけ表示を許可する
 

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。