Handling jump animations

In this recipe, we'll show how the jumping animation can be handled in the animation manager control from previous recipes. Why does this require its own recipe? Animation-wise, jumping is usually a set of sequenced animations. If we look at Jaime, for example, there's JumpStart, Jumping, and JumpEnd. Normally, sequenced animations can be handled in the onAnimCycleDone method; when one animation ends, it can trigger the next. Jumping is different though since the middle jumping animation is indefinite and is on a loop. How long it plays depends on how long the character is in the air, which is driven by the gameplay or its physics.

How to do it...

You can handle jumping animations by performing the following steps:

  1. For this, we'll need to add two more Booleans to our animation control: jumpStarted and inAir.
  2. We trigger the first part of the animation in the onAction method, as shown in the following code. The jumpStarted Boolean is used to let the class know that other animations should not start while the character is the jumping state:
    public void onAction(String binding, boolean value, float tpf) {
      if (binding.equals("Jump") && value) {
        jumpStarted = true;
        setAnimation(Animation.JumpStart);
      }
    }
  3. The onAnimCycleDone method should switch animations back to the jumping action once JumpStart has finished playing. We also set inAir to true, as shown in the following code:
    public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
      if(channel.getLoopMode() == LoopMode.DontLoop){
        Animation newAnim = Animation.Idle;
        Animation anim = Animation.valueOf(animName);
        switch(anim){
          case JumpStart:
            newAnim = Animation.Jumping;
            inAir = true;
            break;
        }
        setAnimation(newAnim, channel);
      }
    }
  4. The controlUpdate method is suitable to check whether the character has landed after jumping (or falling). We check this directly in BetterCharacterControl and change the animation if it is back on the ground, as shown in the following code:
    protected void controlUpdate(float tpf) {
      if(inAir){
        BetterCharacterControl charControl =spatial.getControl(BetterCharacterControl.class);
        if(charControl != null && charControl.isOnGround()){
          setAnimation(Animation.Idle);
          jumpStarted = false;
          inAir = false;
        }
      }
    }

How it works...

The implementation relies on the listener pattern where this control receives a notification of user actions from an external input class. In this project, we have a separate class that controls the character.

This onAnimCycleDone method is called by the AnimControl method when an animation has finished with one cycle (both looping and non-looping animations). Normally, when an animation ends, we'll want to switch to the idle animation to stop it from freezing. When JumpStart is finished, however, the character is most likely in midair and thus switches to a suitable looping animation. The inAir Boolean is used so the class knows it should start checking for when the character lands again.

Depending on the size of a project, the control class for the character and this animation-managing class might be merged into one. This should make some things easier, while the class itself might get bulky as more functions are implemented.

The controlUpdate class is called automatically with every tick, and here we can see whether the character is still airborne. In this implementation, BetterCharacterControl is used, and it has a method to see whether it is on ground. Jaime has a JumpEnd animation, but idle seems to work better with some blending.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.209.131