how to make Sprite follow bezier curve
Asked Answered
A

1

8

Im fairly new to objective-c and sprite kit but i've done games development for a while. Im currently working on a 2d game and i have enemy ships moving from right to left on the screen. Ive been following tutorials for different parts of my game and then adding to it where necessary. I found a tutorial where the in game enemies follow a bezier path and i've managed to implement this in my game however as i'm new to bezier curves i do not fully understand them and the algorithm makes my sprites move from top to bottom but i need them to go left to right.

I have included the code snippet that i have used to add the bezier curve to my sprites any suggestions on how i can have them move right to left instead of top to bottom.

CGMutablePathRef cgpath = CGPathCreateMutable();

        float xStart = [self getRandomNumberBetween:0+asteroid.size.width to:self.frame.size.width-asteroid.size.width];
        float xEnd = [self getRandomNumberBetween:0+asteroid.size.width to:self.frame.size.width-asteroid.size.width];
        float cp1X =[self getRandomNumberBetween:0+asteroid.size.width to:self.frame.size.width-asteroid.size.width];
        float cp1y = [self getRandomNumberBetween:0+asteroid.size.width to:self.frame.size.width-asteroid.size.height];
        float cp2x = [self getRandomNumberBetween:0+asteroid.size.width to:self.frame.size.width-asteroid.size.width];
        float cp2Y = [self getRandomNumberBetween:0 to:cp1y];

        CGPoint s = CGPointMake(xStart, 1024.0);
        CGPoint e = CGPointMake(xEnd, -100);
        CGPoint cp1 = CGPointMake(cp1X, cp1y);
        CGPoint cp2 = CGPointMake(cp2x, cp2Y);
        CGPathMoveToPoint(cgpath, NULL, s.x, s.y);
        CGPathAddCurveToPoint(cgpath, NULL, cp1.x, cp1.y, cp2.x, cp2.y, e.x, e.y);

        SKAction *enemyCurve = [SKAction followPath:cgpath asOffset:NO orientToPath:YES duration:5];

  CGPoint location = CGPointMake(-self.frame.size.width-asteroid.size.width, randY);

        SKAction *moveAction = [SKAction moveTo:location duration:randDuration];
        SKAction *doneAction = [SKAction runBlock:(dispatch_block_t)^(){

            asteroid.hidden = YES;
        }];

        SKAction *moveAsteroidActionWithDone = [SKAction sequence:@[enemyCurve,moveAction, doneAction]];

Thank you for any help and suggestions.

Annunciator answered 5/2, 2015 at 10:49 Comment(0)
T
9

Bezier curves are used to generate a smooth curve between two points. To move the path from left to right, choose a starting point on the left and choosing an ending point on the right. The two control points determine the shape of the path to take from left to right. Varying the startpoint and endpoint in the following code will control where the bezier curve starts and where it ends. Varying the control points vary the shape of the curve. You can see that with the attached GIF.

CGMutablePathRef cgpath = CGPathCreateMutable();

CGPoint startingPoint = CGPointMake(50, 100);

CGPoint controlPoint1 = CGPointMake(160, 250);
CGPoint controlPoint2 = CGPointMake(200, 140);

CGPoint endingPoint = CGPointMake(303, 100);


CGPathMoveToPoint(cgpath, NULL, startingPoint.x, startingPoint.y);
CGPathAddCurveToPoint(cgpath, NULL, controlPoint1.x, controlPoint1.y,
                      controlPoint2.x, controlPoint2.y,
                      endingPoint.x, endingPoint.y);


SKAction *enemyCurve = [SKAction followPath:cgpath asOffset:NO orientToPath:YES duration:5];

[enemy runAction:[SKAction sequence:@[[SKAction waitForDuration:1],enemyCurve]]];

enter image description here

P0 and P3 are the starting and ending points and P1 and P2 are the control points.

Check out this page to play more with bezier curves. http://www.jasondavies.com/animated-bezier/

Tubercular answered 5/2, 2015 at 12:6 Comment(2)
This was what i was looking for, thank you for a good explanation i have managed to implement this into my game and it works.Annunciator
By any chance do you know how i would have the sprite face the direction its moving in, i set orientToPath: YES but it just faces the final point in the curve, any suggestions on how i can get it to point in the direction its traveling? Thank you againAnnunciator

© 2022 - 2024 — McMap. All rights reserved.