phaser
phaser copied to clipboard
When providing frames with duration to anims.create(), 41.6ms is added to every frame (1 frame time @24 FPS)
Version
- Phaser Version: 3.70.0
- Operating system: Windows 11
- Browser: Chrome and FF
Description
When providing durations in animations using an array of frames rather than total duration or FPS, the timing is generally slower than it should, sometimes by over several hundreds of ms or more. This is especially noticeable for quick and snappy animations making it impossible to define animation durations per frame this way.
This scales with the number of frames given to anims.create() EXAMPLE:
this.anims.create({
key: 'walk',
frames: [
{ key: 'brawler', frame: 0, duration: 200 },
{ key: 'brawler', frame: 1, duration: 100 },
{ key: 'brawler', frame: 2, duration: 200 },
{ key: 'brawler', frame: 3, duration: 100 },
],
repeat: 0
});
For each frame, the time is extended by 40ms. So a 10 frame animation will have a total runtime of about 400ms longer.
Example Test Code
Simply refresh, the time displayed on screen should match the total duration for all the frames. In the fiddle is should be 2400ms, but the animation completes in about 3000ms on Chrome or Firefox browser.
I think it's related to the default framerate of 24 FPS and it adds 41.6 ms to each frame. Doing an animation with 1000 frames, duration 1ms per frame I get: 42646ms total remove 1000ms of actual animation and we get 41646ms or pretty close to 41.6ms per frame
A quick look in the animationManager This seems to be fixed for Aseprite imports using createFromAseprite() We find there the following:
// Fix duration to play nice with how the next tick is calculated.
var msPerFrame = totalDuration / animFrames.length;
animFrames.forEach(function (entry)
{
entry.duration -= msPerFrame;
});
Applying this manually before calling create() solved the issue for me, but if durations are provided, I would expect the same behavior as createFromAseprite()
I think that the description for Phaser.Types.Animations.AnimationFrame.duration is wrong and it should be like Phaser.Animations.AnimationFrame#duration.
That is probably a fair point, but It would definitely be nice to set the msPerFrame to be 0 and all durations coming from the supplied frames. Afterall, this is basically required when importing animations from aseprite as the user specifies all frametimes manually, it's odd to not have a built-in way in Phaser to do the same.
To keep it consistent, being that "fix" for Aesprite shouldn't be needed, msPerFrame is no longer added to duration.
Thank you for submitting this issue. We have fixed this and the fix has been pushed to the master branch. It will be part of the next release. If you get time to build and test it for yourself we would appreciate that.
I think 2e4b43b is technically a breaking change, because AnimationFrame#duration did correctly describe Phaser's behavior.
All the animations in my game are running faster after upgrading to 3.80. Could it be related to this ? What's the fix ?
Only when applying a duration to a frame, as it no longer applies an additional msPerFrame, so the duration is the actual length of the frame.
To compare speed of animations you can use this example and change between versions: https://labs.phaser.io/view.html?src=src\animation\show%20animation%20play%20through.js