0

シーンに追加されたカスタム SKSpriteNode クラスを使用するスプライトがあります。

このエフェクトを実行したい: 3 つのスプライトが並んでいるとします。スプライトに触れた場合、または指が触れている間にスプライトを少し拡大縮小し、指が触れていないとすぐに元のサイズに縮小する必要があります。

つまり、ユーザーが大きな指を左から右にスライドさせ、最初のスプライトから開始して最後のスプライトを通過したとします。指がスライドしているとき、指がフレームに入るとすぐに最初のスプライトが拡大するようにします。指が右にスライドし続けて 2 番目のスプライトに到達すると、最初のスプライトで指がその領域にないことを検出し、元のサイズに縮小します。同時に、指がその領域内にあるため、2 番目のスプライトが拡大されます。スライド中、最後のスプライトを通過した直後に、いつでも指が表面を離れます。

私の問題は、スプライト クラス内のロジックを使用してこれを実行したいということですが、そのスプライトのクラスで touchesBegan、touchesMoved などを実装すると、touchesMoved はその領域内になくても指を報告し続けるため、機能しません。

これは、スプライトのクラス内の私のタッチ ロジックです。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    SKAction *scaleUp = [SKAction scaleTo:1.2 duration:0.2];
    [self runAction:scaleUp];

}


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint touchLocation = [touch locationInNode:self];

//    CGPoint convertPT = [self convertPoint:touchLocation fromNode:self.parent];

    NSLog(@"%@", NSStringFromCGPoint(touchLocation));

//    if (CGRectContainsPoint(self.frame, touchLocation)) {
//        NSLog(@"this is never fired?");
//    }
}

指がレイヤーの外にある場合でも、NSLog行は常に場所を出力します...

指がスプライトの外に出た後、TouchesMoved の発火を停止させたいと思います。

それ、どうやったら出来るの?

4

1 に答える 1

1

これをサブクラスに入れて、良い結果を得ました。

がゲーム シーン クラス内から rect の外側で開始するときのロジックが必要です。

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   SKAction *scaleUp = [SKAction scaleTo:1.2 duration:0.2];
   [self runAction:scaleUp withKey:@"action"];
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches) {

        UITouch* touch = [touches anyObject];
        CGPoint loc = [touch locationInNode:self.parent];

        if (![self containsPoint:loc]) {
            SKAction *scaleDown = [SKAction scaleTo:1.0 duration:0.1];
            [self runAction:scaleDown];
        }
        else if ([self containsPoint:loc]) {
            SKAction *scaleUp = [SKAction scaleTo:1.2 duration:0.1];
            [self runAction:scaleUp];
        }
    }
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self removeActionForKey:@"action"];
    SKAction *scaleDown = [SKAction scaleTo:1.0 duration:0.1];
    [self runAction:scaleDown];
}

私はサブクラスのメソッドを自分の好みに合わせて動作させていませんが、メインシーンからうまく動作させることができました - 混乱してif statementsいます...しかし、仕事はします

// add a ivar to scene enforce one zoom spite at a time,  SKSpriteNode *_currentZoomRect;

- (void) addSomeBlocks
{
    for (int i = 1; i <= 3; i++) {
        SKSpriteNode *rect = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor] size:CGSizeMake(70, 70)];
        rect.position = CGPointMake(100 * i , 160);
        rect.name = @"inner";
        [self addChild:rect];
    }
}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches) {

        UITouch* touch = [touches anyObject];
        CGPoint loc = [touch locationInNode:self];
        NSArray *nodes = [self nodesAtPoint:loc];

        for (SKNode *n in nodes) {
            if ([n.name isEqualToString:@"inner"]) {
                _currentZoomRect = (SKSpriteNode *) n;
                SKAction *scaleUp = [SKAction scaleTo:2.0 duration:0.05];
                [n runAction:scaleUp withKey:@"action"];
            }
        }
    }
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches) {

        UITouch* touch = [touches anyObject];
        CGPoint loc = [touch locationInNode:self];
        NSArray *nodes = [self nodesAtPoint:loc];

        for (SKNode *n in nodes) {

            if ([n.name isEqualToString:@"inner"]) {

                if (_currentZoomRect) {
                    // can only allow one zoom at a time
                    if (n == _currentZoomRect  && !n.hasActions) {
                        SKAction *scaleUp = [SKAction scaleTo:2.0 duration:0.05];
                        [n runAction:scaleUp];
                    }

                    else if (n != _currentZoomRect) {

                        SKAction *scaleDown = [SKAction scaleTo:1.0 duration:0.05];
                        [_currentZoomRect runAction:scaleDown];

                        SKAction *scaleUp = [SKAction scaleTo:2.0 duration:0.05];
                        [n runAction:scaleUp];
                        _currentZoomRect = (SKSpriteNode *) n;
                    }
                }
                else {
                    SKAction *scaleUp = [SKAction scaleTo:2.0 duration:0.05];
                    [n runAction:scaleUp];
                    _currentZoomRect = (SKSpriteNode *) n;
                }
            }
        }

        if (![nodes count] && _currentZoomRect) {

            SKAction *scaleDown = [SKAction scaleTo:1.0 duration:0.05];
            [_currentZoomRect runAction:scaleDown];
            _currentZoomRect = nil;

        }
    }
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (_currentZoomRect) {
        SKAction *scaleDown = [SKAction scaleTo:1.0 duration:0.05];
        [_currentZoomRect runAction:scaleDown];
        _currentZoomRect = nil;
    }
}
于 2013-10-13T23:30:05.670 に答える