2

我是 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"];
        }
    }

}
4

1 回答 1

3

我将 绑定UITouch到 Sprite on touchesBegan, unbind on touchesEnded。然后在每次更新时UITouch使用单极过滤器逼近该位置。

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


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


雪碧

@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]; }

于 2014-02-15T04:33:05.580 回答