Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

1 decade ago by Joncom

EDIT As it turned out the thread name is missleading. Frames were not being skipped, but rather not selected when it was expected they would be.

-----------

When I run currentAnim.gotoFrame(11), you would think currentAnim.frame would then be set to 11. But it is not. Why?

To demonstrate the problem I ran the following:
var frameCount = ig.game.player.currentAnim.sequence.length;
for(var i=0; i<frameCount ; i++) {
    ig.game.player.currentAnim.gotoFrame(i);
    var frame = ig.game.player.currentAnim.frame;
    if(i !== frame) {
        console.log('Called gotoFrame(' + i + ') but frame is still ' + frame);
    }
}

The output:
Called gotoFrame(11) but frame is still 10
Called gotoFrame(15) but frame is still 14
Called gotoFrame(22) but frame is still 21
Called gotoFrame(30) but frame is still 29

Here is the entirety of my code:
/* main.js */
ig.module('game.main')
.requires('impact.game', 'game.entities.player')
.defines(function(){
    MyGame = ig.Game.extend({
        init: function() {
            this.player = this.spawnEntity(
                EntityPlayer,
                ig.system.width/2,
                ig.system.height/2
            );
        }
    });
    ig.main('#canvas', MyGame, 60, 480, 320, 2);
});

/* player.js */
ig.module('game.entities.player')
.requires('impact.entity')
.defines(function(){
    EntityPlayer = ig.Entity.extend({
        size: {x: 60, y:60},
        animSheet: new ig.AnimationSheet('media/player/aim-grenade.png', 60, 60),
        init: function( x, y, settings ) {
            this.parent( x, y, settings );
            this.addAnim('aimGrenade', 0.03, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
                15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]);
        }
    });
});

Why are certain frames inaccessible?

1 decade ago by Joncom

It seems this happens because of some bad math that's taking place.

Within the gotoFrame method, a timer is set like this:
this.timer.set( this.frameTime * -f );
// frameTime == 0.03
// f == 11

So the timer is therefor set like this:
timer.set( 0.03 * -11 );

And simplified further yet:
this.timer.set( -0.33 );

However, by setting a breakpoint using Chrome developer tools, I observed that the value passed into timer.set is not -0.33.

It's -0.32999999999999996!

So the timer is being set just short of the value necessary to reach the correct frame.

1 decade ago by Joncom

For me this was a problem, because I needed manual control over which frame is being displayed at any given moment. For most people who let timers handle the animating, the correct frame would be selected very soon-after. So for most people this is a non-issue.

That said, here is my fix:
ig.module('plugins.joncom.go-to-frame-fix.animation')
.requires('impact.animation')
.defines(function(){ "use strict";
    ig.Animation.inject({
        gotoFrame: function( f ) {
            var seconds = (this.frameTime * -f).round(6);
            this.timer.set(seconds);
            this.update();
        },
    });
});

Available on Github as well.

1 decade ago by quidmonkey

Floating point rounding errors!

Might be a good reason to make Impact 2.0 ig.Timer ms based vs. s based.

The fix is to bring the update logic into gotoFrame:
gotoFrame: function ( f ) {
	this.timer.set(this.frameTime * -f);

	// manually set proper frame to prevent
	// floating point errors
	this.frame = f;
	this.tile = this.sequence[ f ];
}

1 decade ago by dominic

Oh wow. Thanks for investigating!

I believe setting the this.frame manually still has some quirks: if afterwards the animation's update() method is called again, the timer's delta hasn't changed and the animation will be set to the wrong frame again.

I believe this would fix the problem, but it still looks quite hack-ish:
this.timer.set( this.frameTime * -f - 0.0001 );

Objections? :)

Edit: the fix is in the Impact git repository on your download page
Page 1 of 1
« first « previous next › last »