First off, I would like to know why in the hell you want to keep track of the time when you started to jump and started to fall, that seems weird. Unless you are putting some sort of delay between jumps or whatever.
Imo the best way to handle such things is using a FSM and components for your entity, such as ActionJump, ActionAttack etc. I’ll write up an example, give me 10 :p.
Ok here is what I came up with, I kinda forgot why I was doing this and started to actually code a class…
Standard FSM to handle the states, the FSM is probably familar to you but regardless I implemented it because it allows you to manage components of entities nicely:
public class Player {
/* That's right, we on the moon */
float gravity = 1.622f;
/*
* States are just purely data, they do not do anything on their own.
*/
public enum PlayerState {
RUNNING, JUMPING, FALLING;
}
/*
* This is the current state the player will be in, we change this to
* determine what our update method does
*/
PlayerState currentState;
/*
* I presume you know this basic stuff, putting it in here mostly for sugar
* to give the class a more solid look
*/
public float acceleration;
public float maxSpeed;
public Vector2 velocity = new Vector2();
JumpAction jumpAction;
public Player() {
jumpAction = new JumpAction(this);
}
public void update(float delta) {
/* Push the player down with gravity */
velocity.y -= gravity;
/*
* Check jump attempts, since we can jump in any state (maybe, assuming
* we can do 1 jump even when falling), jump the wee bastard
*/
if (Gdx.input.isKeyPressed(Keys.SPACE)) {
currentState = PlayerState.JUMPING;
jumpAction.execute();
}
/*
* Now we do a switch statement on our current state and decide what to
* do
*/
switch (currentState) {
case RUNNING:
/*
* We probably shouldn't do this here but whatever, check for input
* and apply acceleration in the correct direction
*/
if (Gdx.input.isKeyPressed(Keys.A)) {
if (Math.abs(velocity.x) < maxSpeed)
velocity.x += -acceleration;
} else if (Gdx.input.isKeyPressed(Keys.D))
if (Math.abs(velocity.x) < maxSpeed)
velocity.x += acceleration;
break;
case JUMPING:
jumpAction.update(delta);
// Do other things, maybe check for certain collision types or wait
// for callbacks on certain surfaces. Whatever really, depends how
// OOP you want to be.
/*
* Ama gonna check if the Y velocity has started to go down as
* opposed to up, then like add fall damage or something
*/
if (velocity.y < 0)
currentState = PlayerState.FALLING;
break;
case FALLING:
// Maybe update a falling component
// Check for collisions so we can flag the chracter as grounded and
// change back to another state
default:
break;
}
}
}
The JumpAction class, handles jump timing and the jump itself. It could do a lot more, such as setting flags on the entity for jumps. After all, it is in charge of jumps:
public class JumpAction {
Player player;
/*
* This is the amount of time we have been in this state, don't mix up this
* with the FSM, it has nothing to do with it. It is simply the timing mechanism
* for the state of this action
*/
float stateTime;
public JumpAction(Player player) {
this.player = player;
}
public void execute(){
/* Apply an upwards force to the players velocity, instantly */
player.velocity.y = 10;
}
public void update(float delta){
/* There, timing done. Is that simple */
stateTime += delta;
// Do something with this timing thing
}
}