Jump to content

Varying Animation FPS


Recommended Posts

Hi everyone

I'm having trouble trying to implement an animation where each frame renders at a different rate.

This is the standard way of adding animations to a sprite: sprite.animations.add("key", ["frame_1", "frame_2", "frame_3", ... , "frame_n"], FPS, loop);

So frame_1 through frame_n all render at a uniform rate which is specified by the FPS argument.


However, I want to create an animation where, for example, frame_1 plays at 30FPS, frame_2 plays at 10FPS, frame_3 plays at 60FPS, etc. I've looked around everywhere and from what I gather, this cannot be done easily. Is there a fast workaround that does not require going into the source and potentially destroying something?




Link to comment
Share on other sites

Coincidentally, I tried what was suggested shortly after I posted. It almost achieves what I'm looking for, but the shortcoming is that the animations appear very choppy and thus less optimal. Also, it seems like a very hacky workaround. Maybe frame-specific delays will be implemented in Phaser 3?

Link to comment
Share on other sites

It's not a very standard thing that you want to achieve, I'm not surprised that Phaser doesn't handle this for you.

You can always write your own animation handler. If I read it right you want frame 1 to last for 2 ticks, frame 2 for 6 ticks and frame 3 for 1 tick, you could create a function very similar to the `animation.add` function that accepts an array of objects/arrays that specify the frame to display and the duration (in ticks) that you want the frame to last for. This is identical to how you can specify animation frames via CSS or `element.animate` (although in those cases you specify a duration for each animation rather than a frame-rate). You'd have to implement a count which increments each tick and checks against the tick-time you've specified for the current frame and resets the count and grabs the new frame when the time is reached.

In pseudo code it'd be something like:

// add([
//   {
//     imageID: 'frame1',
//     duration: 2
//   },
//   {
//     imageID: 'frame2',
//     duration: 1
//   }
//   ..., ]
//   60 // FPS
// )
function add( frames:array, timer:int ) {
  let count = 0
  let currentFrame = 0
  let frame = null

  start timer at specified frame-rate
    frame = frames[ currentFrame ]
    inc count
    if ( count >= frame.duration ) {
      inc currentFrame
      select next frame (select first frame if at end of frames array)
      set count to 0
      exit loop

    display current frame
  next timer

I dont think with Phaser you have to handle the displaying of the current frame but you would have to set the image representing the sprite so that the renderer knows what to draw. I'm sure you get the idea.

There's probably a number of optimisations and improvements you could make from there. You'd probably want to pass in the game tick loop to save running a different loop. I tend to use a stream for my frame loop, so, for example, I'd listen in for frame events (ticks) and call everything inside the pseudo-code loop each event (often called an update), that might be what the loop variable is for in the Phaser `animation.add` function (I'm not savvy with everything Phaser).

Link to comment
Share on other sites


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...