Speed player for a few seconds

How can I speed up a player for a few frames? seconds? 



I have several Quads. When the player drives over them a collision check is made! Now I want to speed the player to get the nice effect used in Mario Karts :wink:



This is my method so far!



private void checkSpeeder(Spatial n, float time){
      
      if(player.getWorldBound().intersects(n.getWorldBound())) {
            if (n instanceof Node) {
               // Loop through nodes of children
               Node parent = (Node) n;
               for (int i = 0; i < parent.getQuantity(); i++) {
                  checkSpeeder(parent.getChild(i), time);
               }
            } else {
               //collision detected
               //now speed the players velocity up
                        
            }
      }
                    
        
   }



Could somebody help me? Do I have to put the velocity higher or do I have to work with a vector?

Thanks AGAIN ;)

you most likely don't need all of this but this is how i make my characters move



 /**
     * Makes the character Move in a given direction
     * @param theDirection call the enum Direction in order to move in a specific direction
     * @param accel is this character going to be accelerated or not
     */
   public void move(Direction theDirection,boolean accel) {
      isMoving=true;
      boolean isForward = theDirection.equals(Direction.FORWARD) ? true : false;
      player.getLocalTranslation().addLocal
       (theDirection.getDirection(player).mult(accel(accel,isForward)));
      prevDirec = theDirection;
   }
   /*
    * @param accel is this character going to be accelerated or not
    * @param isForward is the character moving forward so MaxSpeed can be modified accordingly
    * @return Speed the accelerated velocity of the character
    */
   private float accel(boolean accel,boolean isForward){
      if(accel||isForward){  //velocity is the desired acceleration
         float Velocity = (float) (isForward==true? MaxSpeed*(2/3.0):MaxSpeed);
         Speed += (gameSingleton.get().timer.getTimePerFrame()) * Velocity;
                                   //if speed is greater than the maximum indented speed Speed = maxSpeed
            if(Speed > Velocity) {   Speed = Velocity;       }
                     }
      else Speed = reSpeed;
      return Speed;
   }
/*@return Speed the decelerated velocity of the character */
   private float deccel(){      //reSpeed is the original speed before acceleration
         Speed -= (gameSingleton.get().timer.getTimePerFrame()) * reSpeed;
         if(Speed < 0) {Speed = 0;}   return Speed;
   }

In FlagRush lessons, they implement a Vehicule node with a accelerate method, called by ForwardAndBackwardAction himself instancied in the FlagRushHandler (himself instancied in the main class). I supposed you can on a collision dectection, call an "speedUp" method on your kart to increase the velocity, with a timer or a thread to decrease the velocity on constant time. And on kart update, you translate the node more far or not.

Or, you create a 'speedRate' in the Vehicul class in 2 states - normal=1 and speedup=2 -, that you change on the Action call, and you multiply it in the update method (velocitytimespeedRate) like that the kart speed 2x.



FlagRushHandler:


KeyBindingManager keyboard = KeyBindingManager.getKeyBindingManager();
keyboard.set("forward", KeyInput.KEY_W);
...
ForwardAndBackwardAction forward = new ForwardAndBackwardAction(node, ForwardAndBackwardAction.FORWARD);
addAction(forward, "forward", true);



ForwardAndBackwardAction :


public void performAction(InputActionEvent evt) {
        if(direction == FORWARD) {
            node.accelerate(evt.getTime());
        } else if(direction == BACKWARD){
            node.brake(evt.getTime());
        }
}



Vehicule:


public void accelerate(float time) {
        velocity += time * acceleration;
        if(velocity > maxSpeed) {
            velocity = maxSpeed;
        }
}
...
public void update(float time) {
        this.localTranslation.addLocal(this.localRotation.getRotationColumn(2, tempVa)
                .multLocal(velocity * time));
        rotateWheels(time);
        processLean(time);
    }



Can't I just say, that when my player hits the box he gets a velocity of 120f for the next 3 seconds ??



I implemented this idea, but when I try it out the velocity of 120f stays all the time! It should just stay for a few seconds!



private void checkSpeedSign(Spatial n, float time){   
      if(player.getWorldBound().intersects(n.getWorldBound())) {
            if (n instanceof Node) {
               // Loop through nodes of children
               Node parent = (Node) n;
               for (int i = 0; i < parent.getQuantity(); i++) {                 
                  checkSpeedSign(parent.getChild(i), time);                 
               }
            } else {
              SoundManager.playSpeederSound();
              float time2 = time + 3;
              if(time2 < Timer.getTimer().getTimeInSeconds()){
                 player.setVelocity(120f);
                 time2++;
                 System.out.println("time2 = " + time2);
              }
               }
       
         }
   }


thanks ;)  will take a closer look on that!

I believe some of the above posters have listed very good solutions for your problem. The code snippet that you produced as an example has flawed logic. On collision with a 'boost' object the else statement will trigger forcing the velocity to 120. Unfortunately that's all it does. You have to create code that keeps track of how long to keep the velocity at 120, and when the time is up to reset the velocity to its normal setting.



Your else statement should be more like



else {

SoundManager.playSpeederSound();

player.setVelocity(120f);

player.setVelocityResetTimer(3);

}



the setVelocityResetTimer will allow you to create another method inside of your player class. This method would be able to hold a global variable that records the time at which the velocity should reset at (in seconds)



public void setVelocityResetTimer(int tempSeconds) {

terminateIncreasedVelocityAt = tempSeconds + Timer.getTimer().getTimeInSeconds();

// you can possibly send the timer as another parameter, or even calculate the parameter with the time added and send it into the function

return;

}



you then create a velocityUpdate class that triggers on every physics update, that simply checks if its time to reset the velocity



public void velocityUpdate() {

if (terminateIncreasedVelocityAt >= Timer.getTimer().getTimeInSeconds()) {

this.setVelocity(60);

}

}



Thats the easiest way, imho to fix your problem, however it is very convoluted and I believe the above posters answers would better serve you in the long run.

It is working now :slight_smile: Mixed a little from all of your codes!



So I have a speedRate in my Player class which is 1! When the player has a collision with a speeder the SpeedRate is 2!



    public void setSpeedRate(float speedRate){
       this.speedRate = speedRate;
    }



To tell the Game that he should speed up for 3 seconds I used the setVelocityResetTimer :


    public void setVelocityResetTimer(int tempSeconds) {
       terminateIncreasedVelocityAt = tempSeconds + Timer.getTimer().getTimeInSeconds();
        // you can possibly send the timer as another parameter, or even calculate the parameter with the time added and send it into the function
       return;
       }



Then on the update of the player I have this:


this.localTranslation.addLocal(this.localRotation.getRotationColumn(2, tempVa)
                .multLocal(velocity * time * speedRate));
       
        if (terminateIncreasedVelocityAt >= Timer.getTimer().getTimeInSeconds()) {
           this.speedRate = 2;           
           }else{
              this.speedRate = 1;
           }



Thanks for all the help! Gonna finish my Game next week and then I will show it ;)