iOS Sprite Kit:如何让Sprite跟随Touches

时间:2014-02-06 07:52:56

标签: ios objective-c sprite-kit skaction

我是Sprite Kit的新手,我想知道如何让精灵跟随触摸。例如,我的播放器精灵位于屏幕的底部。当我点击屏幕顶部时,玩家精灵应该以一定的速度移动到触摸点 - 如果我移动手指,它应该总是指向触摸点。这就是我尝试实现它的方式:

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

    for (UITouch *touch in touches) {

        CGPoint location = [touch locationInNode:self];

        CGPoint diff = rwSub(location, self.player.position);
        CGPoint norm = rwNormalize(diff);

        SKAction *act = [SKAction moveByX:norm.x * 10 y:norm.y * 10 duration:0.1];
        [self.player runAction:[SKAction repeatActionForever:act] withKey:@"move"];


    }
}

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

        CGPoint location = [touch locationInNode:self];

        CGPoint diff = rwSub(location, self.player.position);
        CGPoint norm = rwNormalize(diff);

        SKAction *act = [SKAction moveByX:norm.x * 10 y:norm.y * 10 duration:0.1];
        [self.player runAction:[SKAction repeatActionForever:act] withKey:@"move"];
    }

}

然而,当移动手指时,精灵移动非常迟钝。有没有办法让运动变得美妙动人?

非常感谢任何帮助!

编辑:我想我找到了一个修改了touchesMoved函数的解决方案:

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

        [self.player removeActionForKey:@"move"];
        CGPoint location = [touch locationInNode:self];

        CGPoint diff = rwSub(location, self.player.position);
        CGPoint norm = rwNormalize(diff);

        [self.player setPosition: rwAdd(self.player.position, rwMult(norm, 2))];
        SKAction *act = [SKAction moveByX:norm.x * 10 y:norm.y * 10 duration:0.01];
        [self.player runAction:[SKAction repeatActionForever:act] withKey:@"move"];
        }
    }

}

1 个答案:

答案 0 :(得分:3)

我将UITouch绑定到touchesBegan上的精灵,解除touchesEnded上的绑定。然后在每次更新时使用单极点过滤器接近UITouch位置。

根本不需要采取任何行动,也不需要以这种方式实施touchesMoved。整个东西变得更加封装。


或使用SKPhysicsJointSpring。为触摸创建一个节点,然后创建一个连接您的精灵和触摸节点的弹簧接头。然后仅调整触摸节点位置。


的Sprite

@interface ApproachingSprite : SKSpriteNode
@property (nonatomic, weak) UITouch *touch;
@property (nonatomic) CGPoint targetPosition;
-(void)update;
@end

@implementation ApproachingSprite

-(void)update
{
    // Update target position if any touch bound.
    if (self.touch)
    { self.targetPosition = [self.touch locationInNode:self.scene]; }

    // Approach.
    CGFloat filter = 0.1; // You can fiddle with speed values
    CGFloat inverseFilter = 1.0 - filter;
    self.position = (CGPoint){
        self.targetPosition.x * filter + self.position.x * inverseFilter,
        self.targetPosition.y * filter + self.position.y * inverseFilter,
    };
}

@end

场景

-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*) event
{ self.sprite.touch = [touches anyObject]; }

-(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*) event
{ self.sprite.touch = nil; }

-(void)update:(CFTimeInterval) currentTime
{ [self.sprite update]; }