Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

control max speed in sprite kit

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?

like image 714
Alfro Avatar asked Dec 12 '22 09:12

Alfro


2 Answers

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)
    }
like image 62
Tokuriku Avatar answered Dec 27 '22 10:12

Tokuriku


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

like image 27
Gadget Blaster Avatar answered Dec 27 '22 12:12

Gadget Blaster