iOS Sprite Kit: How to make Sprite follow Touches

给你一囗甜甜゛ 提交于 2020-01-02 17:47:49

问题


I'm new to Sprite Kit and I'm wondering how you can make a sprite follow the touches. For example, my player sprite is on the bottom of the screen. When I tap on the top of the screen, the player sprite should move to the touch point with a certain speed - and if I move my finger it should always be pointing towards the touch point. This is how I tried to implement it:

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

}

However, the sprite moves very laggy when moving the finger. Is there a way I can make the movement nice and smooth?

Any help would be greatly appreciated!

EDIT: I think I have found a solution I modified the touchesMoved function:

- (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:


I'd bind the UITouch to the Sprite on touchesBegan, unbind on touchesEnded. Then on every update approach the UITouch position with a one pole filter.

No need for actions at all, also you don't need to implement touchesMoved this way. The whole stuff become more encapsulated.


Or use SKPhysicsJointSpring. Create a node for the touch, then a spring joint that connects your sprite and the touch node. Then adjust touch node position only.


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

Scene

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



来源:https://stackoverflow.com/questions/21597014/ios-sprite-kit-how-to-make-sprite-follow-touches

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!