0
\$\begingroup\$

I've figured out how to render a GIF image using this library as follows:

@Override
public void simpleUpdate(float tpf) {
    if (bgFrameIndex > 0) {
        guiNode.detachAllChildren();
    }

    guiNode.attachChild(bgNodes.get(bgFrameIndex));

    if (bgFrameIndex < bgDecoder.getFrameCount() - 1) {
        ++bgFrameIndex;
    } else {
        bgFrameIndex = 0;
    }
}

where bgDecoder is a GifDecoder, bgNodes is an ArrayList of nodes that contain the GIF's frames, and bgFrameIndex is the current frame index to render. By default, the tpf (ticks per frame) variable is at around 0.01 seconds, when I want to limit it to the frame delay of the current frame without changing the FPS of the entire game. What's the best way to do this?

EDIT

My new code from the answer of @1000ml (I also fixed frame removal):

private float bgFrameDelay = bgDecoder.getFrameCount() > 0 ? bgDecoder.getDelay(bgFrameIndex) : 0;

@Override
public void simpleUpdate(float tpf) { // ticks per frame
     bgFrameDelay -= tpf;

     if (bgFrameDelay < 0F) {
         bgFrameDelay = bgDecoder.getDelay(bgFrameIndex) / 1000F;

         if (bgFrameIndex > 0) {
             bgNodes.get(bgFrameIndex - 1).removeFromParent();
         }

         guiNode.attachChild(bgNodes.get(bgFrameIndex));

         if (bgFrameIndex < bgDecoder.getFrameCount() - 1) {
             ++bgFrameIndex;
         } else {
             bgFrameIndex = 0;
         }
     }
 }
\$\endgroup\$
0
\$\begingroup\$

Adding a Thread.sleep() call to the simpleUpdate() method will throttle the whole jme thread. This will be very noticable when you add more elements to your application.

Here's a way to skip calls to simpleUpdate() until the desired delay is reached:

private float t = bgDecoder.getDelay(0);

public simpleUpdate(float tpf) {
    t -= tpf;
    if(t > 0f) {
        return;
    }
    t = bgDecoder.getDelay(bgFrameIndex) / 1000f;

    // Your stuff goes here
}

You might have to adjust the frame index, but I hope you get the idea.

\$\endgroup\$
  • \$\begingroup\$ The only problem is leaving your t variable outside the loop. The delay between frames can vary, and the way your code is now has the delay for the first frame used for all frames. I'd also test for our one true case and have the default return option do the work for me, like with if (t < 0F) { // do my stuff } \$\endgroup\$ – T145 Mar 17 '17 at 1:08
  • \$\begingroup\$ You might have to adjust the frame index, but I hope you get the idea. \$\endgroup\$ – 1000ml Mar 17 '17 at 3:12
0
\$\begingroup\$

Ended up just using Thread.sleep(bgDecoder.getDelay(bgFrameIndex)); and everything works perfectly! I'd love to hear any better alternatives.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.