How toget update loop to execute an action once inside a given time frame

I want to make a super-simple jME3 “game” start up, cycle a Ninja model (the Ninja.mesh.xml that ships with the test-data.jar) through 4 animations, choreographed to change animation every 2 seconds, such that:

  • For the first 2 seconds (t <= 2s) the Ninja is walking
  • For 2s > t <= 4s the Ninja is crouching
  • For 4s > t <= 6s the Ninja is idling
  • For 6s > t <= 8s the Ninja is backflipping

My best attempt thus far:

public class Simulator extends SimpleApplication implements AnimEventListener {
    private AnimChannel animationChannel;
    private AnimControl animationController;
    private Node avatar;

    // Constructor, getters/setters, etc.

    @Override
    public void simpleInitApp() {
        viewPort.setBackgroundColor(ColorRGBA.LightGray);
        DirectionalLight directionalLight = new DirectionalLight();
        rootNode.addLight(directionalLight);

        avatar = (Node)assetManager.loadModel("models/Ninja.mesh.xml");
        avatar.localScale = 0.025f;
        rootNode.attachChild(avatar);
        animationController = avatar.getControl(AnimControl);
        animationController.addListener(this);
        animationChannel = animationController.createChannel();

        flyCam.setDragToRotate(true);

        setDisplayFps(false);
        setDisplayStatView(false);
    }

    @Override
    void simpleUpdate(float tpf) {
        globalTime += tpf

        if(globalTime < 2.0) {
            animationChannel.setAnim("Walk", 0.5)
        } else if(globalTime >= 2.0 && globalTime < 4.0) {
            animationChannel.setAnim("Crouch", 0.5)
        } else if(globalTime >= 4.0 && globalTime < 6.0) {
            animationChannel.setAnim("Idle1", 0.5)
        } else {
            animationChannel.setAnim("Backflip", 0.5)
        }
    }

    @Override
    public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
        channel.setAnim('Idle1');
        channel.setLoopMode(LoopMode.DontLoop);
        channel.setSpeed(1f);
    }

    @Override
    public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
        // No-op for now
    }
}

However this is clearly wrong. When I run this, setAnim(...) is being called on every update loop, and so the Ninja looks like he’s having a seizure.

How is this typically solved? How do I only set the animation once inside each of the four time intervals? I have read the tutorials and cannot see anything in all the examples that applies to my use case here.

This seems kind of like basic Java programming to me.

if( globalTime < 2.0 && currentAnim != "Walk" ) {
    currentAnim = "Walk";
    animationChannel.setAnim("Walk", 0.5);
}
....and so on...

I myself am using a design pattern called public subscription. It works like this:

You need a class UpdateProvider and an interface UpdateListener.
In the UpdateProvider, make a list registrations and the functions register (UpdateListener l) and unregister (UpdateListener l). These functions should add/remove the listeners from the list.
In the UpdateListener, simply put the function update (float tpf).

How to update

You need another update function in the UpdateProvider, where you call all the updates from the registrations.

In your Main class, the one that extends SimpleApplication, search the update function and put in that the update fromantic the Provider.

##How to control
Now, this is the easiest part: simply type : UpdateProvider.register (this)

I made this on my tablet, I will add example code and edit some parts later.

Wouldn’t this be unnecesary complication?
For all the things you do there you could just insert some if elses into simpleUpdate().

So you’ve reimplemented app states?

On its own it doesn’t solve OPs problem anyway.

As to that, I answered OPs problem as written but note that there is also the cinematics system which while a bit clunky is deigned for implementing cinematics (uncoincidentally).

Hm.
Yes indeed, @pspeed

It still is pretty handy from time to time.