4
votes

I am programming a game and want to move a sprite along a fixed path (straights and curves - think railroad engine) but I want to be able to drive the animation in terms of the sprites velocity - and change that velocity in response to game events.

followPath:duration: in SKAction is close, but there seems no way to adjust the speed "on the fly" - I definitely care about sprite speed - not 'duration to follow path'.

CGPath seems like the right construct for defining the path for the sprite, but there doesn't seem to be enough functionality there to grab points along the path and do my own math.

Can anyone suggest a suitable approach?

2
refer to this link code.tutsplus.com/tutorials/…Revinder
thanks @Revinder, but that seems to use followPath in the way I described, which does not allow for changing the speed over time.Justin Hawkins
@JustinHawkins, have you found the solution? The same thing you asked I would like to know how to do it.sabiland

2 Answers

5
votes

You can adjust the execution speed of any SKAction with its speed property. For example, if you set action.speed = 2, the action will run twice as fast.

SKAction *moveAlongPath = [SKAction followPath:path asOffset:NO orientToPath:YES duration:60];
[_character runAction:moveAlongPath withKey:@"moveAlongPath"];

You can then adjust the character's speed by

[self changeActionSpeedTo:2 onNode:_character];

Method to change the speed of an SKAction...

- (void) changeActionSpeedTo:(CGFloat)speed onNode:(SKSpriteNode *)node
{
    SKAction *action = [node actionForKey:@"moveAlongPath"];
    if (action) {
      action.speed = speed;
    }
}
1
votes

Try some think like this :

CGMutablePathRef cgpath = CGPathCreateMutable();

//random values
float xStart = [self getRandomNumberBetween:0+enemy.size.width to:screenRect.size.width-enemy.size.width ];
float xEnd = [self getRandomNumberBetween:0+enemy.size.width to:screenRect.size.width-enemy.size.width ];

//ControlPoint1
float cp1X = [self getRandomNumberBetween:0+enemy.size.width to:screenRect.size.width-enemy.size.width ];
float cp1Y = [self getRandomNumberBetween:0+enemy.size.width to:screenRect.size.width-enemy.size.height ];

//ControlPoint2
float cp2X = [self getRandomNumberBetween:0+enemy.size.width to:screenRect.size.width-enemy.size.width ];
float cp2Y = [self getRandomNumberBetween:0 to:cp1Y];

CGPoint s = CGPointMake(xStart, 1024.0);
CGPoint e = CGPointMake(xEnd, -100.0);
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 *planeDestroy = [SKAction followPath:cgpath asOffset:NO orientToPath:YES duration:5];
[self addChild:enemy];

SKAction *remove2 = [SKAction removeFromParent];
[enemy runAction:[SKAction sequence:@[planeDestroy,remove2]]];

CGPathRelease(cgpath);