Jump to content

Collision bug - collision happening randomely?


Recommended Posts

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:



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 Function

create: 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 Methods

checkKeys: 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 Update

update: 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 Idea

As 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

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


  • Recently Browsing   0 members

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