Bullet bounds do not match texture

I’m making a top-down game with a simple tilemap for the player to walk around using the keyboard. The player can shoot bullets using a Phaser.Weapon.

There appears to be a difference between the rotation of the bullet bounding box and the bullet texture. When the Weapon is aimed at a particular angle, the resulting bullets appear to be rotated correctly. However, the collision detection says otherwise:

  • When shooting horizontal surfaces, the bullet goes into the wall until it is exactly half submerged
  • When shooting vertical surfaces, the bullet collides prematurely. This is most noticeable at an angle

After some experimentation, I deduced that the bullet bounding box was fixed as a “wide” rectangle. So when shooting up, the texture appears as a “tall” bullet, but the bounding box is actually rotated at 90 degrees as a “wide” bullet. The rotation of the bounding box appears to be the same regardless of the shooting angle, an idea supported by examining the top and bottom properties of the Bullet, which always reflect the “thin” orientation of the bullet.

This is perhaps best demonstrated by a video. I am using long, slow-moving bullets to make this clearer.

Further details:

  • Phaser CE 2.10
  • Arcade physics. Body is enabled on player
  • Collision detection between player bullets and tiles:
        bullet => bullet.kill()
  • Creation of bullet texture:
    const bulletGraphics = game.add.graphics(0, 0)
    bulletGraphics.lineStyle(3, 0x000000)
    bulletGraphics.moveTo(0, 0)
    bulletGraphics.lineTo(bulletLength, 0)
    const bulletTexture = bulletGraphics.generateTexture()
  • Creation of bullets inside Weapon subclass constructor: this.createBullets(numberOfBullets, bulletTexture)
  • Aiming at x, y with Weapon: this.fireAngle = radToDeg(angleBetween(player.world.x, player.world.y, x, y))

How can I keep the bullet texture and bounding box in sync to avoid these strange collisions?

In Arcade Physics the body is always an axis-aligned rectangle (or a circle). If you don’t modify the body then it will be a rectangle with the same dimensions of the unrotated texture.

Use game.debug.body(…) so you can see the body dimensions.

If you don’t need exact collisions then make the body a 3 × 3 square aligned on the sprite’s center.

If you do need exact collisions, I can think of two ways:

  1. Make the bullet body a square with length bulletLength, centered on the sprite. In collide(), use a processCallback, calculate where the endpoints are, and return true or false.
  2. Use two small invisible bodies for the bullet endpoints. Check collisions with them instead.
1 Like

Thanks once again, samme. For now, I’m going with smaller bullets to avoid this issue. I did look into adjusting the bullet bodies, but found adjusting the body’s position to match the tip of the bullet sprite too fiddly for what it was worth. But this solution is fine for now. In the worst case in future, I can simply migrate to a different physics system if Arcade proves to be too limiting.

The debug mode is very useful and illustrated your point well.