Creating a retaining polygon collider shape

Hi all,

Pretty new to Phaser. I’m building my first game user Phaser 3 and I have a a player character that starts on a boat. I would like for this character be contained in the boat’s area.

Looking at the docs, I know I need some sort of Polygon collider. I’m struggling to figure out how to apply a collider boundary that is a polygon.

You can see the area I am trying to contain the player below (shaded in purple):

You can find my code here:

Any help would be greatly appreciated! Thanks in advance!

1 Like

2 Likes

Hi @samme,

Thanks so much for providing this example. I have been referencing documentation on it, and got it working for my purposes. However, I would love to understand from a top-level, what all the working parts of the code do.

Mainly just the projectRect(), setBlocked(), and clampVelocity().

I have a feeling that this same concept will come up in another scene or another game I’ll be making, and I’d love to to get a general grasp.

Thanks again!

Arcade Physics doesn’t deal in polygons so you have to do these checks yourself. You can use the Geom classes/methods.

This example doesn’t try to do collision separation with the polygon, which is more complicated. Instead it uses a rectangle as a proxy for the player body, projects the rectangle forward based on the provisional velocity (from input), checks if every corner of the rectangle is within the polygon, then clamps (zeroes) the provisional velocity in the direction of any corner that is outside. So it doesn’t actually find the edge of the polygon, but since the projection vector is small (2.6px), it gets close enough.

body.blocked is an existing property that can be borrowed for this purpose. The physics engine will reset it before each update, so we don’t have to.

My clamp function may make more sense this way:

function clampVelocity(velocity, blocked) {
  if (blocked.left && velocity.x < 0) velocity.x = 0;
  if (blocked.right && velocity.x > 0) velocity.x = 0;
  if (blocked.up && velocity.y < 0) velocity.y = 0;
  if (blocked.down && velocity.y > 0) velocity.y = 0;
}
1 Like