dopepope Posted May 24, 2014 Share Posted May 24, 2014 This thread talks about the finished product in the phaser tutorial described here:http://www.photonstorm.com/phaser/tutorial-making-your-first-phaser-gameAfter using the arrow keys to walk around, your character sometimes comes to a stop like this:Which when zoomed in, looks like this:However, other times your character comes to a stop like this:Which when zoomed in, looks like this:How do I ensure that sprites do not interpolate or alias across two locations one pixel apart? That is, how do I make sure that sprites always display the first way and never the second way?(This possible bug was first noticed on 2.0.1. Updating to 2.0.5 did not help.)For reference, here is the code:var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });function preload() { game.load.image('sky', 'assets/sky.png'); game.load.image('ground', 'assets/platform.png'); game.load.image('star', 'assets/star.png'); game.load.spritesheet('dude', 'assets/dude.png', 32, 48);}var player;var platforms;var cursors;var stars;var score = 0;var scoreText;function create() { // We're going to be using physics, so enable the Arcade Physics system game.physics.startSystem(Phaser.Physics.ARCADE); // A simple background for our game game.add.sprite(0, 0, 'sky'); // The platforms group contains the ground and the 2 ledges we can jump on platforms = game.add.group(); // We will enable physics for any object that is created in this group platforms.enableBody = true; // Here we create the ground. var ground = platforms.create(0, game.world.height - 64, 'ground'); // Scale it to fit the width of the game (the original sprite is 400x32 in size) ground.scale.setTo(2, 2); // This stops it from falling away when you jump on it ground.body.immovable = true; // Now let's create two ledges var ledge = platforms.create(400, 400, 'ground'); ledge.body.immovable = true; ledge = platforms.create(-150, 250, 'ground'); ledge.body.immovable = true; // The player and its settings player = game.add.sprite(32, game.world.height - 150, 'dude'); // We need to enable physics on the player game.physics.arcade.enable(player); // Player physics properties. Give the little guy a slight bounce. player.body.bounce.y = 0.2; player.body.gravity.y = 300; player.body.collideWorldBounds = true; // Our two animations, walking left and right. player.animations.add('left', [0, 1, 2, 3], 10, true); player.animations.add('right', [5, 6, 7, 8], 10, true); // Finally some stars to collect stars = game.add.group(); // We will enable physics for any star that is created in this group stars.enableBody = true; // Here we'll create 12 of them evenly spaced apart for (var i = 0; i < 12; i++) { // Create a star inside of the 'stars' group var star = stars.create(i * 70, 0, 'star'); // Let gravity do its thing star.body.gravity.y = 300; // This just gives each star a slightly random bounce value star.body.bounce.y = 0.7 + Math.random() * 0.2; } // The score scoreText = game.add.text(16, 16, 'score: 0', { fontSize: '32px', fill: '#000' }); // Our controls. cursors = game.input.keyboard.createCursorKeys(); }function update() { // Collide the player and the stars with the platforms game.physics.arcade.collide(player, platforms); game.physics.arcade.collide(stars, platforms); // Checks to see if the player overlaps with any of the stars, if he does call the collectStar function game.physics.arcade.overlap(player, stars, collectStar, null, this); // Reset the players velocity (movement) player.body.velocity.x = 0; if (cursors.left.isDown) { // Move to the left player.body.velocity.x = -150; player.animations.play('left'); } else if (cursors.right.isDown) { // Move to the right player.body.velocity.x = 150; player.animations.play('right'); } else { // Stand still player.animations.stop(); player.frame = 4; } // Allow the player to jump if they are touching the ground. if (cursors.up.isDown && player.body.touching.down) { player.body.velocity.y = -350; }}function collectStar (player, star) { // Removes the star from the screen star.kill(); // Add and update the score score += 10; scoreText.text = 'Score: ' + score;} Link to comment Share on other sites More sharing options...
lewster32 Posted May 24, 2014 Share Posted May 24, 2014 This is not really a bug, just a by-product of the fact that the physics systems work with floating point numbers, and Phaser isn't a framework dedicated to pixel art. Try this at the end of the update function maybe?player.x = player.x | 0;player.y = player.y | 0;This will round the x and y position of the player, which should prevent it landing between pixels. Link to comment Share on other sites More sharing options...
dopepope Posted May 24, 2014 Author Share Posted May 24, 2014 Rounding the y location messes up the collision with ground for some reason, but rounding the x location fixes the problem. Thanks a lot! Link to comment Share on other sites More sharing options...
lewster32 Posted May 24, 2014 Share Posted May 24, 2014 The collision issue may be because the ground's body doesn't lie exactly on a pixel boundary either. Rather than scaling the ground sprite, you may want to try explicitly setting the size of the body with body.setSize() and try again just to be sure. I should add that player.x | 0 will always round down, but it's very fast. You could also try player.x = Math.round(player.x) and see how that differs. Link to comment Share on other sites More sharing options...
David Posted May 25, 2014 Share Posted May 25, 2014 I should add that player.x | 0 will always round down, but it's very fast. If you want to have it round to the nearest integer, you can do(player.x + 0.5) | 0 Link to comment Share on other sites More sharing options...
PAEz Posted May 25, 2014 Share Posted May 25, 2014 @David : Hey, thats cool....another thing I hadnt seen lately.Just out of interest I put that through jsperf.....http://jsperf.com/math-floor-vs-math-round-vs-parseint/126....dont ya just hate results like that? Nice to see IE still sucks.....really? a function call is faster than a bitwise operation?.....ok..... Link to comment Share on other sites More sharing options...
lewster32 Posted May 25, 2014 Share Posted May 25, 2014 Also slightly confusing is that the | 0 rounding routine is faster if you add another operation to it... Oh JavaScript. Link to comment Share on other sites More sharing options...
slash Posted July 16, 2016 Share Posted July 16, 2016 This question is pretty old but still one of the top results on google so I thought it'd be nice to update it. This can now be fixed with the antialias param when creating the game: var transparent = false; var antialias = false; var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', this, transparent, antialias); Link to comment Share on other sites More sharing options...
Recommended Posts