Jump to content

Sprite Gap


Recommended Posts

WARNING: Wall of text incoming. Sorry. :(


Sorry for the crappy topic title, but I actually don't even know what to title this as. :S


I'll do my best to convey what's going on. In my game I have 22 teeth that scroll across the screen. When one tooth leaves the bounds on the left it gets re positioned on the right just outside the game bounds to scroll back in. However as you will see in the screenshots below, as the game progresses they slowly become displaced little by little. The first few teeth position correctly but the rest are off by a couple pixels. That gap however continuously gets larger.


Things I've Looked Into

  • I looked into optimizing my JavaScript code but what I quickly realized was that even turning off EVERYTHING in the update loop except for the scrolling teeth that same gap showed up and it wasn't any less prominent
  • I thought the sprite size might be weird, but the sprite sheet has 6 frames each frame being 80 pixels wide and the anchor set at 0.5, 0.5 so I'm pretty sure it's not that
  • I looked into memory consumption thinking maybe GC calls were causing blips in frame rate but through chromes profiler and turning everything off except for tooth movement, memory consumption was only at 5 or so MB and frame rate NEVER dropped below 60 FPS
  • I looked into Object Pooling with groups so that a new tooth isn't created every time one goes off screen but rather the old tooth is just reused and re-positioned.

After looking into all of these I just can not figure it out for the life of me. o.O Hopefully someone can help me get a better understanding of what could be going on.



The screenshot above shows the teeth perfectly lined up as soon as the game starts. However if you look hard to the right side you'll see about a pixel of the background next to the teeth. This will become more prominent in the screenshot below.



As the teeth move a bit more, you now clearly see the gap in between each tooth. Yet some teeth seem to position correctly while others don't.



I left the game running to see what would happen. As I expected, the gap becomes more and more prominent as the game continues to run. I looked at the profiler in Chrome and there was next to no memory increase. At this point I have no idea what's going on :S


Here is the code that does the initial placement as well as the movement.

'use strict';var Tooth = function(game, x, y, frame, rotation) {	Phaser.Sprite.call(this, game, x, y, 'tooth', frame);  	this.anchor.setTo(0.5, 0.5);	// initialize your prefab here	this.game.physics.arcade.enableBody(this);	this.body.allowGravity = false;	this.body.immovable = true;		this.animations.add('toothHeal');	this.cleanTooth = 0;	this.pointValue = 10;	// Respawn position on the X axis	this.xRespawnPos = this.game.width + (this.width * 0.5);	// Set the velocity of each tooth	this.body.velocity.x = -350;};Tooth.prototype = Object.create(Phaser.Sprite.prototype);Tooth.prototype.constructor = Tooth;Tooth.prototype.update = function() {	// Check out of bounds	if (this.x < Math.ceil(-this.width * 0.5))	{		this.resetTooth();	}};Tooth.prototype.resetTooth = function(){		this.x = this.xRespawnPos;	this.cleanTooth = 0;	this.animations.frame = 0;};module.exports = Tooth;
'use strict';var Tooth = require('./tooth');var TeethGroup = function(game, parent) {	Phaser.Group.call(this, game, parent);		// Spawn initial amount of teeth to start the game	for (var i = 0; i < 11; ++i) 	{		// Initialize a top and bottom tooth		this.topTooth = new Tooth(this.game, 0, 0, 1);				this.bottomTooth = new Tooth(this.game, 0, 0, 1);		// Set the position & rotation of each top & bottom tooth		this.topTooth.x = this.topTooth.width * i;		this.topTooth.y = this.topTooth.height / 2;		this.topTooth.angle = 180;		this.add(this.topTooth);		this.bottomTooth.x = this.topTooth.width * i;		this.bottomTooth.y = this.game.height - this.topTooth.height / 2;		this.add(this.bottomTooth);		};};TeethGroup.prototype = Object.create(Phaser.Group.prototype);TeethGroup.prototype.constructor = TeethGroup;TeethGroup.prototype.stop = function(){	this.setAll('body.velocity.x', 0);};module.exports = TeethGroup;

Hopefully someone can point out something that I clearly looked over. Any help is greatly appreciated. Thanks in advance!

Link to comment
Share on other sites

Try flooring or ceiling your multiplications with 0.5.


this line:  this.xRespawnPos = this.game.width + (this.width * 0.5);


try:  this.xRespawnPos = this.game.width + Math.floor(this.width * 0.5);


I believe I tried that before, but to make sure, I just tried it again. No difference unfortunately... 

Link to comment
Share on other sites

Instead of using velocity try this:

Tooth.prototype.update = function() {  this.x = (this.x - (350 * (this.game.time.elapsed / 1000))) | 0;};

This is a totally framerate independent way of moving the teeth to the left at 350px per second, and rounding down their position each time.


I think the other problem may be the maths involved in the way you're detecting when a sprite goes off the screen to the left and repositioning it off the right of the screen. When the sprite goes past the left of the screen, it may do so by an arbitrary amount since it's moving more than 1 pixel per frame. You'll probably need to take this overshoot into account and add it to the position it gets repositioned to on the right, otherwise gaps will start to form. I think (but my maths isn't great) that when you cull the object you add the difference between the cull point (-sprite.width) and the sprite's position when you cull it to the respawn position.


It's a little difficult to explain so let me know if I'm not making any sense! I solved a similar problem to this recently making a Frogger style game and keeping the gaps between the moving sprites even.

Link to comment
Share on other sites

So... Thanks for all the replies but... it turns out it was something ridiculously simple... as usual.


Original code

var Tooth = function(game, x, y, frame, rotation) {	Phaser.Sprite.call(this, game, x, y, 'tooth', frame);...	this.xRespawnPos = this.game.width + this.width * 0.5;...};

Updated and fixed code

Tooth.prototype.resetTooth = function(){		this.x += this.xRespawnPos;...};

The difference is the plus equals. Previously I was just hard setting the X but because the update N times per second then there was also probably a frame where it would just move a pixel. That just added up over time and made the gaps bigger and bigger.

Link to comment
Share on other sites


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...