Cavaleri Posted June 24, 2015 Share Posted June 24, 2015 Hi I seem to be facing a very annoying issue. I am working on a Pacman inspired game and I based the movement off of the "Move like Pacman" tutorial from the learn examples on Phaser.io:http://phaser.io/tutorials/coding-tips-005 The bug/error I am facing is that the player/sprite randomely collides with tiles that he is not supposed to be colliding with. You can check it out yourself by playing a few minutes on http://cavagames3.meteor.com Here's the relevant code I am using - I rewrote the learn example a bit but these changes should logically be causing the issue. Especially since the issue was present even before I began rewriting it. The Create Functioncreate: function () { // Create the map (object) this.map = this.add.tilemap('map'); this.map.addTilesetImage('tileset', 'tiles'); this.layer = this.map.createLayer('Pacman'); // Create the array of safe tiles to spawn & to add random Dots to this.safeTileArray = this.createTileArray(this.safetile); [... extra code ...] // Pacman should collide with everything except the safe tile this.map.setCollisionByExclusion([this.safetile], true, this.layer); [... extra code ...] },The Relevant MethodscheckKeys: function () { if (this.cursors.left.isDown && this.current !== Phaser.LEFT) { this.checkDirection(Phaser.LEFT); } else if (this.cursors.right.isDown && this.current !== Phaser.RIGHT) { this.checkDirection(Phaser.RIGHT); } else if (this.cursors.up.isDown && this.current !== Phaser.UP) { this.checkDirection(Phaser.UP); } else if (this.cursors.down.isDown && this.current !== Phaser.DOWN) { this.checkDirection(Phaser.DOWN); } else { // This forces them to hold the key down to turn the corner this.turning = Phaser.NONE; } }, checkDirection: function (turnTo) { if (this.turning === turnTo || this.directions[turnTo] === null || this.directions[turnTo].index !== this.safetile) { // Invalid direction if they're already set to turn that way // Or there is no tile there, or the tile isn't index 1 (a floor tile) return; } // Check if they want to turn around and can if (this.current === this.opposites[turnTo]) { this.move(turnTo); } else { this.turning = turnTo; this.turnPoint.x = (this.marker.x * this.gridsize) + (this.gridsize / 2); this.turnPoint.y = (this.marker.y * this.gridsize) + (this.gridsize / 2); } }, turn: function () { var cx = Math.floor(this.pacman.x); var cy = Math.floor(this.pacman.y); // This needs a threshold, because at high speeds you can't turn because the coordinates skip past if (!this.math.fuzzyEqual(cx, this.turnPoint.x, this.threshold) || !this.math.fuzzyEqual(cy, this.turnPoint.y, this.threshold)) { return false; } // Grid align before turning this.pacman.x = this.turnPoint.x; this.pacman.y = this.turnPoint.y; this.pacman.body.reset(this.turnPoint.x, this.turnPoint.y); this.move(this.turning); this.turning = Phaser.NONE; return true; }, move: function (direction) { var speed = this.speed; if (direction === Phaser.LEFT || direction === Phaser.UP) { speed = -speed; } if (direction === Phaser.LEFT || direction === Phaser.RIGHT) { this.pacman.body.velocity.x = speed; } else { this.pacman.body.velocity.y = speed; } if (direction === Phaser.LEFT) { this.pacman.play('munch-left'); } else if (direction === Phaser.UP) { this.pacman.play('munch-up'); } else if (direction === Phaser.DOWN) { this.pacman.play('munch-down'); } else if (direction === Phaser.RIGHT) { this.pacman.play('munch-right'); } this.current = direction; },The Actual Updateupdate: function () { [... extra code ...] // collision between the pacman, walls and dots this.physics.arcade.collide(this.pacman, this.layer); this.physics.arcade.overlap(this.pacman, this.dots, this.eatDot, null, this); // collision between the pacman and upgrades this.physics.arcade.overlap(this.pacman, this.upgradeEaters, this.eatUpgradeEater, null, this); // Calculate the grid position of the Pacman this.marker.x = this.math.snapToFloor(Math.floor(this.pacman.x), this.gridsize) / this.gridsize; this.marker.y = this.math.snapToFloor(Math.floor(this.pacman.y), this.gridsize) / this.gridsize; // Update our grid sensors this.directions[1] = this.map.getTileLeft(this.layer.index, this.marker.x, this.marker.y); this.directions[2] = this.map.getTileRight(this.layer.index, this.marker.x, this.marker.y); this.directions[3] = this.map.getTileAbove(this.layer.index, this.marker.x, this.marker.y); this.directions[4] = this.map.getTileBelow(this.layer.index, this.marker.x, this.marker.y); // Check if a key is pressed down this.checkKeys(); if (this.turning !== Phaser.NONE) { this.turn(); } [... extra code ...] }Alternative IdeaAs an alternative, I tried adding another layer above it with tile #17 overlapping every "wall" in the map. Then i changed the setCollisionByExclusion to setCollision(17, true, SECOND LAYER). This does however give the exact same results as the above code does where collision happens randomely on tiles where it should not.I tried debugging and printing getTileLeft, getTileRight, getTileAbove, getTileBelow to the console, and it appears that the tiles that it collides with are indeed the ones that it should not collide with. Any help will be highly appreciated as I am completely stuck with this issue!Thanks a lot! Link to comment Share on other sites More sharing options...
Cavaleri Posted June 25, 2015 Author Share Posted June 25, 2015 Just in case anyone faces the same problem as I did - I managed to create a work around for this problem. Run the following function right above your collision check in the update() loop.avoidRandomCollision: function(){ // make sure that this is not run if the getTileDirection is null if (this.map.getTileLeft(this.layer.index, this.marker.x, this.marker.y) && this.map.getTileRight(this.layer.index, this.marker.x, this.marker.y) && this.map.getTileAbove(this.layer.index, this.marker.x, this.marker.y) && this.map.getTileBelow(this.layer.index, this.marker.x, this.marker.y)){ // If the user is trying to go left if (this.current == Phaser.LEFT && this.map.getTileLeft(this.layer.index, this.marker.x, this.marker.y).index == this.safetile){ this.pacman.body.checkCollision.left = false; }else if (this.current == Phaser.RIGHT && this.map.getTileRight(this.layer.index, this.marker.x, this.marker.y).index == this.safetile){ this.pacman.body.checkCollision.right = false; }else if (this.current == Phaser.UP && this.map.getTileAbove(this.layer.index, this.marker.x, this.marker.y).index == this.safetile){ this.pacman.body.checkCollision.up = false; }else if (this.current == Phaser.DOWN && this.map.getTileBelow(this.layer.index, this.marker.x, this.marker.y).index == this.safetile){ this.pacman.body.checkCollision.down = false; }else{ this.pacman.body.checkCollision.left = true; this.pacman.body.checkCollision.right = true; this.pacman.body.checkCollision.up = true; this.pacman.body.checkCollision.down = true; } } },I have not yet commented this section but it should be rather self explanatory. It simply disables the collision in what direction the user is facing entirely, if the tile in front of him is one that he is allowed to walk upon. Link to comment Share on other sites More sharing options...
Recommended Posts