SpriteKitでチェックボックスを実装する
こないだの続き。
チェックボックスを実装してみたのでメモ。
着信があったときのシミュレーションをしようと思ったけど、
お友達がいないのでテスト出来ないです、こんにちは!
こないだは、ボタンっぽい挙動を実装した訳ですが、
今回はチェックボックスということで、
タッチしたらチェックが入ったり、消えたりするアレを実装してみる。
ボタンはSKLabelNodeを使って、frameプロパティを膨らませて、
タッチした位置がその中に含まれるかチェックしたけど、
この辺りの処理はほとんど同じ。
その代わりやらなくちゃいけないことは、
ラベル以外にもチェックする枠、及びレ点の表示を切り替えること。
で、結果的にこんな感じになった。
// FOOCheckBox.h
#import <SpriteKit/SpriteKit.h>
@interface FOOCheckBox : SKSpriteNode
+(instancetype)checkBoxWithTexture:(SKTexture *)texture andText:(NSString *)text;
@property (nonatomic, assign, setter = setChecked:) BOOL checked;
@end
// FOOCheckBox.m
#import "FOOCheckBox.h"
static const float kBetweenMargin = 2.0f;
static NSString *kNodeNameCheckedOff = @"checked.off";
static NSString *kNodeNameCheckedOn = @"checked.on";
@implementation FOOCheckBox
+(instancetype)checkBoxWithTexture:(SKTexture *)texture andText:(NSString *)text
{
SKTexture *textureOff = [SKTexture textureWithRect:CGRectMake(6/8.0, 3/8.0, 1/8.0, 1/8.0)
inTexture:texture];
SKSpriteNode *spriteOff = [SKSpriteNode spriteNodeWithTexture:textureOff];
spriteOff.name = kNodeNameCheckedOff;
SKTexture *textureOn = [SKTexture textureWithRect:CGRectMake(7/8.0, 3/8.0, 1/8.0, 1/8.0)
inTexture:texture];
SKSpriteNode *spriteOn = [SKSpriteNode spriteNodeWithTexture:textureOn];
spriteOn.name = kNodeNameCheckedOn;
SKLabelNode *myLabel = [SKLabelNode labelNodeWithFontNamed:@"Menlo Regular"];
myLabel.text = text;
myLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
myLabel.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
myLabel.fontColor = [SKColor blackColor];
myLabel.fontSize = 14.0f;
const float w = textureOn.size.width + kBetweenMargin + myLabel.frame.size.width;
const float h = textureOn.size.height;
FOOCheckBox *checkBox = [FOOCheckBox spriteNodeWithColor:[UIColor clearColor]
size:CGSizeMake(w, h)];
spriteOff.position = CGPointMake( (w * -.5f) + (textureOff.size.width * .5f), .0f );
[checkBox addChild:spriteOff];
spriteOn.position = CGPointMake( (w * -.5f) + (textureOn.size.width * .5f), .0f );
[checkBox addChild:spriteOn];
myLabel.position = CGPointMake( (w * -.5f) + kBetweenMargin + textureOn.size.width, .0f );
[checkBox addChild:myLabel];
return checkBox;
}
-(void)setChecked:(BOOL)checked
{
_checked = checked;
[self childNodeWithName:kNodeNameCheckedOff].alpha = ( _checked ) ? .0f : 1.0f;
[self childNodeWithName:kNodeNameCheckedOn].alpha = ( _checked ) ? 1.0f : .0f;
}
@end
フォントサイズは、チェックボックスの枠に合わせるので、
あんまし良くないけどコードに書いてある通り。
で、生成後にcheckedプロパティを初期化することを前提にしている。
checkBoxWithTextureで初期化した方が良かったかな。。。
あとは、タッチされたかどうかをframeプロパティを使って判定する。
用途としては、あまりたくさんUIを並べたりしないことを前提に、
BGMやSoundEffectのOn/Offを設定するのに使う。
あと、テクスチャを引数で受け取る必要もないと思う。
なんなら、チェック状態がOnとOffの画像を用意して、
checkBoxWithTextureで読み込んでも良いかも知れない。
ちなみに、タッチの判定に使う範囲は、
CGRectInsetを使ってframeプロパティを8pxほど膨らませてる。
今作ってるアプリに関して言うと、十分に要求を満たしている。
追記 2014/04/30
hiddenプロパティを使えば表示/非表示が切り替えれるので、
こっちを使うのが良いですね。
おしまい。
Leave a Comment