johncintron Posted March 26, 2016 Share Posted March 26, 2016 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? Cheers, JC Link to comment Share on other sites More sharing options...
VitaZheltyakov Posted March 26, 2016 Share Posted March 26, 2016 Dublicate frame: sprite.animations.add("key", ["frame_1", "frame_1", "frame_2", "frame_2", "frame_2", "frame_2", "frame_2", "frame_2", "frame_2", "frame_3", ... , "frame_n"], FPS, loop); Link to comment Share on other sites More sharing options...
johncintron Posted March 26, 2016 Author Share Posted March 26, 2016 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 More sharing options...
mattstyles Posted March 26, 2016 Share Posted March 26, 2016 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 More sharing options...
Recommended Posts