I'm trying to control the max speed of my character in my game. When I move him I use this:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint positionInScene = [touch locationInNode:self];
SKSpriteNode *touchedNode = (SKSpriteNode *)[self nodeAtPoint:positionInScene];
CGPoint posicionHero = [self childNodeWithName:@"hero"].position;
SKSpriteNode *touchHero = (SKSpriteNode *)[self nodeAtPoint:posicionHero];
if((touchedNode !=touchHero) //jump forward
&& (positionInScene.x > [self childNodeWithName:@"Hero"].position.x)
&& (positionInScene.y > [self childNodeWithName:@"Hero"].position.y)
)
{
[[self childNodeWithName:@"Hero"].physicsBody applyImpulse:CGVectorMake(5,0)];
[[self childNodeWithName:@"Hero"].physicsBody applyImpulse:CGVectorMake(0, 10)];
NSLog(@"jump forward done");
}
But the problem is the speed is not limited, and when i do this two or three times the character goes very fast. I tried with a lot of properties (velocity, angular speed, etc) and i didn't found anything satisfactory. Does anybody know how to set a speed limit or any "trick" to control the max speed of a character?
The best approach for me is the following because it makes sure the vector speed is not faster in diagonals:
/* Clamp Velocity */
// Set the initial parameters
let maxVelocity = CGFloat(100)
let deltaX = (self.physicsBody?.velocity.dx)!
let deltaY = (self.physicsBody?.velocity.dy)!
// Get the actual length of the vector with Pythagorean Theorem
let deltaZ = sqrt(pow(deltaX, 2) + pow(deltaY, 2))
// If the vector length is higher then the max velocity
if deltaZ > maxVelocity {
// Get the proportions for X and Y axis compared to the Z of the Pythagorean Theorem
let xProportion = deltaX / deltaZ
let yProportion = deltaY / deltaZ
// Get a new X and Y length in proportion to the max velocity
let correctedDeltaX = xProportion * maxVelocity
let correctedDeltaY = yProportion * maxVelocity
// Assign the new velocity to the Node
self.physicsBody?.velocity = CGVector(dx: correctedDeltaX, dy: correctedDeltaY)
}
This is working good.
- (void)didEvaluateActions
{
CGFloat maxSpeed = 600.0f;
if (self.heroShip.physicsBody.velocity.dx > maxSpeed) {
self.heroShip.physicsBody.velocity = CGVectorMake(maxSpeed, self.heroShip.physicsBody.velocity.dy);
} else if (self.heroShip.physicsBody.velocity.dx < -maxSpeed) {
self.heroShip.physicsBody.velocity = CGVectorMake(-maxSpeed, self.heroShip.physicsBody.velocity.dy);
}
if (self.heroShip.physicsBody.velocity.dy > maxSpeed) {
self.heroShip.physicsBody.velocity = CGVectorMake(self.heroShip.physicsBody.velocity.dx, maxSpeed);
} else if (self.heroShip.physicsBody.velocity.dy < -maxSpeed) {
self.heroShip.physicsBody.velocity = CGVectorMake(self.heroShip.physicsBody.velocity.dx, -maxSpeed);
}
}
Thanks to the answer by @Andrew & the comments by @LearnCocos2D & @Andy
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With