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
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?
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.
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) {
// 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 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));