jMonkeyEngine Animation

Taken from Chapter 7

Click to Learn More

Introduction

Animation is an important aspect in most games. Using animation injects dynamic behavior into a game and can make it a more pleasing and interesting affair. Animation can be used to make a character walk, a ship move across a sea, or a door open and close.

JME3 supports animation using simple techniques based on the simpleUpdate method; model animation supplied by a model; movement of a character or object through a series of predefined points in a game; and with Cinematics. The last technique uses a series of steps which can combine movement, sound, animation, and HUD updates.

We start the chapter off with examples of using the simpleUpdate method and tpf variable to control simple animations. While this is not as powerful as the other animation techniques discussed in this chapter, it is a simple and quick technique for handling some basic animations.

Many animations are based on complex 3D models developed with other applications. JME3 allows us to load many of the models and control the animations embedded within these models. These types of animations are often easier to handle. However, we are reliant upon other tools such as Blender to create the models.

The topic of cinematics is then covered starting with a discussion of way points. These points are simple Vector3f objects representing points in the scene. An object can be made to move through a path defined by these points. Cinematics is also illustrated where we combine movement with sound.

The last section describes how many of this chapter’s techniques are incorporated into the Shades of Infinity game. These include the use of motion paths and cinematics to move the AI ships separately.

Animation Basics

At the most basic level, animation simply involves moving an object that would otherwise be static. The easiest way to animate an object is to apply a transformation to the object repeatedly.

In this section we will examine the use of the tpf variable more closely and how the Application class’ speed variable can be used. Bear in mind that the tpf variable is used in many places and the techniques discussed here are equally applicable wherever the variable is found.

Animating with the simpleUpdate Method

Creating a simple animation in the update loop involves applying a transformation to an object in simpleUpdate. An object is transformed, by the specified amount, every frame. You may recall that we did this with our planetary system in Chapter 4 where we moved the AI ships along a straight path as shown here:

   public void simpleUpdate(float tpf) {

      shootables.move(0.1f * tpf, 0, 0);

   }

The use of a movement transformation is a simple one. We could have used more complex transformations such as a scale or rotate or even a combination of transformations. We used the tpf (time per frame) variable to support a smooth transformation (as explained in the next section).

Using tpf to Control the Speed of an Animation

The tpf parameter is used in a number of update methods including the simpleUpdate method. It represents the amount of time, in seconds, since the last time the update was called. It is larger for slower computers or more computationally intensive applications. It is smaller for faster machines or where the computations are simpler.

To illustrate its use, we will move a simple cube across the scene. In the following sequence, which should be placed in the simpleInitApp method, lights and axes and a simple box are added to the scene using the helper method getBox. The drawAxes method was used in Chapter 1 and the addLights method was introduced in Chapter 6. The variable cubeNode is declared as an instance variable of type Box to allow access from multiple methods.

    drawAxes();

    addLights();

    cubeNode = getBox(“Simple Cube”, 0.5f, 0.5f,

        0.5f, ColorRGBA.Blue);

    cubeNode.setLocalTranslation(0, 0, 0);

    cubeNode.rotate(0, FastMath.DEG_TO_RAD * 45, 0);

    rootNode.attachChild(cubeNode);

    …

    private Node getBox(String name, float width,

            float height, float depth, ColorRGBA color) {

        Node boxNode = new Node(name);

        Box box = new Box(width, height, depth);

        Geometry boxGeometry = new Geometry(name, box);

        Material mat = new Material(assetManager,

            “Common/MatDefs/Light/Lighting.j3md”);

        mat.setBoolean(“UseMaterialColors”, true);

        mat.setColor(“Diffuse”, ColorRGBA.White);

        mat.setColor(“Ambient”, color);

        mat.setColor(“Specular”, ColorRGBA.White);

        mat.setFloat(“Shininess”, 128f);

        boxGeometry.setMaterial(mat);

        boxNode.attachChild(boxGeometry);

        return boxNode;

    }

The simpleUpdate method is modified as shown next.  The move method will move the cube along the X axis at a rate determined by the expression: 0.5f * tpf.

    public void simpleUpdate(float tpf) {

        cubeNode.move(0.5f * tpf, 0, 0);

    }

The 0.5f value controls the rate at which the cube will move. The larger the value, the faster the cube will move. This, combined with the tpf variable, results in the smoother movement of objects. If the tpf is small, the object does not move as far. If the tpf is large, the object will move farther. If we had used a variable for the 0.05f value instead, we could control the rate that multiple objects move at (all expressed as a factor of this variable).

The tpf variable can also be used as a simple clock. In the next example, a currentTime variable keeps track of elapsed time. When it reaches 1.0f, one second has elapsed. The variable currentTime is declared as an instance variable of type float to allow access from multiple methods.

    public void simpleUpdate(float tpf) {

        currentTime += tpf;

        if (currentTime > 1.0f) {

            // Do something

            currentTime = 0.0f;

        }

    }

Using the speed Variable

The speed variable is defined in the Application class. It represents the relative speed of your game and is initialized to 1.0f. You can use it to speed up the game by setting it to a different value. As shown here the speed of the game is increased by a factor of 5:

    speed = 5*speed;

Depending on the machine in use, faster values can affect how well 3D graphics are rendered. Some effects, such as how fast a sound is played, are not affected.