SpriteKitでポーズの実装(後編)

TriShootのレーティングがおかしなことになってるのを、
先ほど気付いて凹んでおります、こんばんは。

という訳で、とりあえず、
プロジェクト名を「Sample」、Prefixを「FOO」にして、
これに対してポーズを実装してみたいと思います。

Prefixを「FOO」にしたので、”FOOMyScene.m”が存在していると思います。
まず、これをシミュレータで実行すると、
タッチしたところにSapceshipが追加されて、回転するはずです。

次に、”Hello, World!”が表示されている範囲を参照したいので、
“Hello, World!”を表示しているSKLabelNodeの参照を確保します。

#import "FOOMyScene.h"

@interface FOOMyScene () {
    SKLabelNode *_helloWorld;
}
@end

@implementation FOOMyScene

-(id)initWithSize:(CGSize)size {    
    if (self = [super initWithSize:size]) {
        /* Setup your scene here */
        
        self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
        
        SKLabelNode *myLabel = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
        
        myLabel.text = @"Hello, World!";
        myLabel.fontSize = 30;
        myLabel.position = CGPointMake(CGRectGetMidX(self.frame),
                                       CGRectGetMidY(self.frame));

        _helloWorld = myLabel;
        [self addChild:_helloWorld];
    }
    return self;
}

importの下辺りに数行追加して、initWithSizeの後半も数行変更しました。

そして、”Hello, World!”がタッチされた場合は、
Sapceshipを追加しないで、独自の処理を行うようにします。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */
    
    for (UITouch *touch in touches) {
        CGPoint location = [touch locationInNode:self];

        if ( CGRectContainsPoint(_helloWorld.frame, location) ) {
            // todo: 独自の処理
            NSLog( @"Label touched." );
            continue;
        }

        SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
        
        sprite.position = location;
        
        SKAction *action = [SKAction rotateByAngle:M_PI duration:1];
        
        [sprite runAction:[SKAction repeatActionForever:action]];
        
        [self addChild:sprite];
    }
}

どこを変更したか分かりましたか?
実行して、”Hello, World!”をタッチすると、
ログが出力されると思います。

さて、次はポーズの実装です。
マルチタッチに対応するのは面倒くさいので、
こんな感じで変更しました。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */
    
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];

    if ( CGRectContainsPoint(_helloWorld.frame, location) ) {
        self.paused = !self.paused;
    }
    else {
        SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
        
        sprite.position = location;
        
        SKAction *action = [SKAction rotateByAngle:M_PI duration:1];
        
        [sprite runAction:[SKAction repeatActionForever:action]];
        
        [self addChild:sprite];
    }
}

これで、”Hello, World!”をタッチすると、
ポーズしたり、ポーズを解除したりできるようになりました。
(これに関して言えば、)簡単ですね。

でも、実際はBGMのOn/Offを行ったり、
違う要因でポーズする必要があったり、
ポーズ中でもupdateメソッドが呼ばれるのでガードする必要があります。

ちなみにポーズ中は、
FOOMySceneに追加されているすべてのノードは停止するようです。
もし、どーしても何かアニメーションをさせたい場合は、
updateメソッドで処理することで対応できます。

TriShootでは、updateメソッドにPAUSEのラベルを点滅させる処理を書きました。

さて、このままだとポーズ中でもSapceshipが追加されてしまいます。
ここから先は、各自でなんとかしてください。

おしまい。

Leave a Comment