0

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

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

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

我的问题是我想在 sprite 类中使用逻辑来执行此操作,但是当我在 sprite 的类上实现 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

我把它放在一个子类中并得到了很好的结果。

当从游戏场景类中的矩形之外开始时,您仍然需要一些逻辑。

- (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 回答