Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drag SKSpriteNode based on touch location

I am trying to drag a sprite in the y axis but make the sprite "stick" to the users finger depending on where the touches began on the node. The sprite is currently dragging but it seems to be snapping the anchorpoint of the sprite to the touch location within the node.

Im assuming it has something to do with getting the location within the node by doing [touch locationInNode:selectedNode]; but I am unsure where to go from there.

Here is my current code.

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

    for (UITouch *touch in touches) {
        CGPoint location  = [touch locationInNode:self];
        SKNode *node = [self nodeAtPoint:location];
        CGPoint newPosition = CGPointMake(node.position.x, location.y);

        if ([node.name isEqualToString:self.selectedNode] ) {

            if (newPosition.y > 230) {
                newPosition.y = 230;
            }
            node.position = newPosition;
        }
    }
}
like image 585
justMike Avatar asked May 02 '14 21:05

justMike


2 Answers

You need to offset the newPosition based on the current touch position on the node.

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

    for (UITouch *touch in touches) 
    {
        CGPoint location  = [touch locationInNode:self];
        SKNode *node = [self nodeAtPoint:location];


        if ([node.name isEqualToString:self.selectedNode] )
        {
            CGPoint previousLocation = [touch previousLocationInNode:self];
            float diff = location.y - previousLocation.y;
            CGPoint newPosition = CGPointMake(node.position.x, node.position.y + diff);


            if (newPosition.y > 230) {
                newPosition.y = 230;
            }
            node.position = newPosition;
        }
    }
}
like image 161
ZeMoon Avatar answered Oct 03 '22 00:10

ZeMoon


There are a couple of ways of doing this. The sample code below tracks the user's touch location and moves the sprite towards that position during the update method. You can modify the code to only move on the y axis or x axis.

@implementation MyScene
{
    SKSpriteNode *object1;
    CGPoint destinationLocation;
}

-(id)initWithSize:(CGSize)size
{
    if (self = [super initWithSize:size])
    {
        [self createObject];
        destinationLocation = CGPointMake(300, 150);
    }
    return self;
}

-(void)createObject
{
     object1 = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(50, 50)];
     object1.position = CGPointMake(300, 150);
    [self addChild:object1];
}

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

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    destinationLocation = [touch locationInNode:self.scene];
}

-(void)update:(CFTimeInterval)currentTime
{
    float x = fabs(object1.position.x - destinationLocation.x);
    float y = fabs(object1.position.y - destinationLocation.y);

    float divider = 0;
    if(x > y)
    {
        divider = x;
    } else
    {
        divider = y;
    }

    float xMove = (x/divider)*8; // change number to increase or decrease speed
    float yMove = (y/divider)*8; // change number to increase or decrease speed

    if(object1.position.x > destinationLocation.x)
        object1.position = CGPointMake(object1.position.x-xMove, object1.position.y);

    if(object1.position.x < destinationLocation.x)
        object1.position = CGPointMake(object1.position.x+xMove, object1.position.y);

    if(object1.position.y > destinationLocation.y)
        object1.position = CGPointMake(object1.position.x, object1.position.y-yMove);

    if(object1.position.y < destinationLocation.y)
        object1.position = CGPointMake(object1.position.x, object1.position.y+yMove);
}

@end
like image 24
sangony Avatar answered Oct 03 '22 01:10

sangony