Drag SKSpriteNode (follow finger movements) with SKPhysics (collision)

Want to drag SKSpriteNode (follow finger movements) using SKPhysics (conflict enabled)

2 unsuccessful solutions:

1)

a) Solution: reposition SKSpriteNode

b) Problem: SKSpriteNode "magically" unexpectedly passes through the wall when the user quickly drags the spriteNode through the wall (physics seems to be inoperative)

c) code:

@property (nonatomic) CGPoint translationBy;

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    [self selectNodeForTouch:positionInScene];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    CGPoint previousPosition = [touch previousLocationInNode:self];

    CGPoint translation = CGPointMake(positionInScene.x - previousPosition.x, positionInScene.y - previousPosition.y);

    [self panForTranslation:translation];
}

- (void)panForTranslation:(CGPoint)translation {
    CGPoint position = [_selectedNode position];
    if([[_selectedNode name] isEqualToString:PLAYER_NAME]) {
        [_selectedNode setPosition:CGPointMake(position.x + translation.x, position.y + translation.y)];
    }
}

2) After searching here, you will find this advice from @ LearnCocos2D "When you use physics, follow the movement of the physical body with the help of force, momentum or changing the speed of the body directly." So I tried:

a) Solution: Apply momentum to the node sprite.

b) : node , node. ( . , , , node , , , .)

c) :

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    [self selectNodeForTouch:positionInScene];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    CGPoint previousPosition = [touch previousLocationInNode:self];

    CGPoint translation = CGPointMake(positionInScene.x - previousPosition.x, positionInScene.y - previousPosition.y);

    CGVector forceVector = CGVectorMake(translation.x, translation.y);
    [self.player.physicsBody applyImpulse:forceVector];
    //[self.player.physicsBody setVelocity:CGVectorMake(0, 0)];

}

- โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’ โ†’

:

: "i) node , : , . ii) node , node , ".

a) : ?

b) : node () .

c) :

@property (nonatomic) CGPoint translationBy;

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    CGPoint previousPosition = [touch previousLocationInNode:self];
    //    1) You could determine the distance of the node to the finger location,

    CGPoint xyTranslation = CGPointMake(positionInScene.x - previousPosition.x, positionInScene.y - previousPosition.y);
    if (fabsf(positionInScene.x - previousPosition.x) < kPlayerMovementThreshold) {
        xyTranslation.x  = 0;
    }
    if (fabsf(positionInScene.y - previousPosition.y) < kPlayerMovementThreshold) {
        xyTranslation.y = 0;
    }
    self.translationBy = xyTranslation;
}

static const CGFloat kPlayerMovementSpeed = 55.0f;

static const CGFloat kPlayerMovementThreshold = 1.0f;

-(void)update:(CFTimeInterval)currentTime{
     // ii) then set the velocity every update: so that it will exactly be on the finger position the next frame.

    CGFloat dx = self.translationBy.x*kPlayerMovementSpeed;
    CGFloat dy = self.translationBy.y*kPlayerMovementSpeed;
    CGVector velocityVector = CGVectorMake(dx,dy);
    [self.player.physicsBody setVelocity:velocityVector];
}
+4
1

, , SKNode, "a", , . node SKPhysicsJointSpring node, , 'b'. node a , spring , node b . node b , , .

+2

Source: https://habr.com/ru/post/1548509/


All Articles