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 paulstraw

First off, Dominic: Impact is insanely cool, and just what I've been looking for for quite some time.

Now on to the problem. I'm working on my first game with Impact, and seem to be having trouble with choppy movement. Any time I do something like this, the resulting movement is pretty choppy (taken directly from the "Jump N Run" demo):

if( ig.input.state('left') ) {
	this.accel.x = -accel;
	this.flip = true;
}

Biolab, etc run just fine on my system though, so I'm not quite sure what I'm doing wrong. I just did another test where I literally copied the Jump N Run source and replaced the sprites/map, and I'm getting the same thing. Any ideas?

Edit: Here's a YouTube video demonstrating the problem. YouTube's compression makes it a little hard to see, but I think the idea probably comes across okay.

1 decade ago by dominic

Woah, interesting! I noticed that the Jump'n'Run example game has this problem too. It's even more noticeable in the Physics demo, because there's no animation for the player when moving.

The only reason this problem is not that obvious in Biolab Disaster is because of the damping for the screen movement.

Here's what's happening; your game's update method probably looks something like this (taken from the Jump'n'Run demo):
update: function() {
	// screen follows the player
	var player = this.getEntitiesByType( EntityPlayer )[0];
	if( player ) {
		this.screen.x = player.pos.x - ig.system.width/2;
		this.screen.y = player.pos.y - ig.system.height/2;
	}
	
	// Update all entities and BackgroundMaps
	this.parent();
}

So this method moves the screen to center on the player's position. However, after the screen x and y were set, the call to this.parent() updates and moves all entities. So the screen is essentially always centered on the position the player had in the last frame. It's always one frame behind.


To fix this, you first have to call this.parent() to update all entities and then set the screen position. Furthermore you also have to call .setScreenPos() for all background maps after you set the screen position. This is normally done in the parent's update() method, but we have to do it again, since we changed this.screen.x/y after the call to this.parent().

But that's still not all - an entity's position is rounded before it's being drawn, so you have to round the screen position as well to make sure it's not choppy.

Long story short: this should work, but is quite ugly:

update: function() {
	// Update all entities and BackgroundMaps
	this.parent();
	
	// screen follows the player
	var player = this.getEntitiesByType( EntityPlayer )[0];
	if( player ) {
		this.screen.x = player.pos.x.round() - ig.system.width/2;
		this.screen.y = player.pos.y.round() - ig.system.height/2;
	}

	// update the screen position for all background maps
	for( var i = 0; i < this.backgroundMaps.length; i++ ) {
		this.backgroundMaps[i].setScreenPos( this.screen.x, this.screen.y);
	}
}

Or - and this is way more elegant at the moment - set the game's screen position from within the update() method of the entity you want to follow, instead of from the game's update() method. So in your game class, don't do anything special:
update: function() {
	// Update all entities and BackgroundMaps
	this.parent();
}

(You could get rid of the update() method in your game class entirely if you only call this.parent())

But in your player entity's update() method, set the screen position after the entity has been moved:
update: function() {
	/* 
		check your input, 
		set the acceleration etc. 
	*/
	
	// move!
	this.parent();
	
	// set the screen position
	ig.game.screen.x = this.pos.x.round() - ig.system.width/2;
	ig.game.screen.y = this.pos.y.round() - ig.system.height/2;
}

I hope that helps!


This is really broken and way more complicated than it should be. Maybe I'll just introduce a .setScreenPos() method for the Game class that you have to call, instead of setting screen.x/y yourself.

I'm sorry for that. Thanks for bringing it to my attention!

1 decade ago by paulstraw

Thanks for the quick, awesome response! I went ahead and set the screen position from within the player entity's update() for now, and that works great. Glad to know I wasn't just doing something dumb, hah.

1 decade ago by gikdew

wow! this really help me!!

Changing this.parent(); to the top of the function make my game run smoothly!

AWESOME!
Page 1 of 1
« first « previous next › last »