SpriteKit - TouchesMoved继续报告精灵外的触摸?

时间:2013-10-13 18:08:31

标签: iphone ios ipad sprite-kit

我有一个使用自定义SKSpriteNode类添加到场景的精灵。

我想做这个效果:假设我有3个精灵并排。我希望精灵在触摸时或手指触摸它时稍微缩放一下,一旦手指没有接触它,它就应该缩小回原来的大小。

我的意思是:假设用户从左到右滑动一个大手指,从第一个精灵开始,到最后一个精灵结束。当手指滑动时,我希望第一个精灵在手指进入其框架时立即向上扩展。当手指继续向右滑动并到达第二个精灵时,我希望第一个手指检测到手指不在其区域上并缩小到原始大小。与此同时,第二个精灵会向上扩展,因为现在手指在其区域内。在滑动过程中手指离开表面的任何时候,在通过最后一个精灵之后。

我的问题是我想在sprite类中使用逻辑但是当我在sprite的类上实现touchesBegan,touchesMoved等时,它不起作用,因为touchesMoved继续报告手指,即使它不在里面它的区域。

这是我在sprite类中的触摸逻辑:

- (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在手指在精灵之外时停止射击。

我该怎么做?

1 个答案:

答案 0 :(得分: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 ...但是工作 < / p>

// 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;
    }
}