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

Here's a video of what I'm trying to accomplish:
http://youtu.be/sKOtBe58m-4

Basically, what I'd like to do is be able to draw (for example) a 4x4 tile section, all using the same tile.

(I know in the video there are two different ones, but it should really do the same thing even if the flowers were all the same color).

Then I'd like the game to render each tile's animation slightly different, based on it's x and y positions.

They all share a common animation:
var flowerAnimation = new ig.AnimationSheet( 'media/flower.png', 16, 16 );
ig.game.backgroundAnims = { 'media/master.png': {
3: new ig.Animation( animationSheet0, 0.13333, [1,2,3,4,5,6,7,8] ) 
} };

The problem is that I believe if I change which frame the animation is on for one, it changes it for all the rest too. Ie. if I adjust them to be different from each other, it won't matter because all I'm adjusting is the one animation that they ALL reference.

Is there a way to accomplish this that does not require creating several separate animations which all use the same graphics?

1 decade ago by paulh

randomly select start frame?

1 decade ago by Joncom

Each tile is one frame ahead of the one to its left and also the one below. There's a definite pattern... not very random.

1 decade ago by dominic

I would create a subclass of ig.Animation that offsets the current animation frame by the world x/y coordinates when drawing. Something like this (untested):

// Yay, that's a catchy class name \o/
ig.PositionDependantAnimation = ig.Animation.extend({
	draw: function( x, y ) {
		// Make the frame dependant on the world position (add screen position)
		var f = this.frame + x + ig.game._rscreen.x + y + ig.game._rscreen.y;
		
		// Select the tile, wrap for sequence.length
		this.tile = this.sequence[ Math.floor(f) % this.sequence.length ];
		
		// Call original draw function
		this.parent( x, y );
	}
});

And then just create your backgroundAnims object with ig.PositionDependantAnimation() instances, instead of ig.Animation().

1 decade ago by paulh

Just out of interest, what is this:


ig.game._rscreen.x

1 decade ago by dominic

Good question; I guess this should really be in the docs. I explained it in IRC a few days ago:
The gist of the problem is, that the background gets drawn at Math.round(bgpos), whereas entities would be drawn at Math.round(entpos - bgpos), which is not always the same as Math.round(entpos) - Math.round(bgpos).
This little rounding error is quite visible. hence the ig.game._rscreen dance


So, in short, _rscreen is the screen position that is "synchronized" with the background and gets rid of that rounding error.

I've thought a while about a better API, but the only thing I can come up with are getters/setters which would break compatibility. Impact 2.0 will have a more sensible approach to this.

1 decade ago by Joncom

Perhaps _rscreen addresses a rounding issue, but there is then another issue.

While the player is moving, animations are constantly flickering. This stops when the player stops.

Any idea why this would happen?

EDIT This issue completely resolved itself when I replaced the line:
var f = this.frame + x + ig.game._rscreen.x + y + ig.game._rscreen.y;

...with this line:
var f = this.frame + x + ig.game.screen.x + y + ig.game.screen.y;

1 decade ago by Joncom

Many thanks Dominic. This solution is much more elegant than what I came up with before I saw your response. Cheers.

ig.PositionDependantAnimation = ig.Animation.extend({
    draw: function( x, y ) {
        
        // Find the position of tile within the world
        var posInMapX = x + ig.game.screen.x;
        var posInMapY = y + ig.game.screen.y;

        // How many tiles are to the left since last 'base animation'?
        var frameOffsetX = (posInMapX/ig.game.collisionMap.tilesize) % (this.sequence.length - 1);
		
		// How many tiles are above since last 'base animation'?
		var frameOffsetY = (posInMapY/ig.game.collisionMap.tilesize) % (this.sequence.length - 1);
		
		// As frameOffsetY increases, shift animation right
		var frameOffset = frameOffsetX - frameOffsetY;
		if(frameOffset<0) frameOffset = (this.sequence.length - 1) + frameOffset;
		
		// Make the frame dependant on the world position (add frame offset)
        var f = this.frame + frameOffset;
        
        // Select the tile, wrap for sequence.length
        this.tile = this.sequence[ Math.floor(f) % this.sequence.length ];
        
        // Call original draw function
        this.parent( x, y );
    }
});
Page 1 of 1
« first « previous next › last »