# How do you properly implement level boundaries in a physics room?

I have an issue with creating a proper boundary in GameMaker Studio when using a physics enabled room.

My room has a gravity of 0, as it is in Space. My player object has the default values, but a friction of 10 with a box shaped collision shape. I also use View0 on a 1280x720 room with a 1280x720 view. That is to be able to do screen shakes and other neat effects.

I really struggle with containing my player object properly to the room. When I use a collision with view0_boundary and add

phy_position_x = phy_position_previousx;
phy_position_y = phy_position_previousy;


then my ship would get stuck at the screen borders very frequently.

I also tried adding some sprites that block the player off the room and created a sprite, 1280x720 and spawned them at the borders. I gave my player empty events for them and set their density to 0, making them static. However, this resulted in the same problem, I got stuck in them.

I need a smooth solution for this, obviously, to have a fun experience. I have this problem quite for a while, so please help me understanding how to do this properly.

I don't know the specifics of GameMaker, but this is how I achieved this effect in Unity.

First I defined a Boundary class that defines the limits of the play area. This class includes a method trimToBoundary that takes an arbitrary coordinates and clamps them to the boundary space, like this

Mathf.Clamp (x, xMin, xMax),
Mathf.Clamp (y, yMin, yMax),


Then in the player controller, I apply a force to the player ship when the player press the move button, and then fix the position by trimming it to the play area boundary.

transform.position = levelController.playersBoundary.trimToBoundary(transform.position.x,transform.position.y);


My code is inspired by this Unity3D tutorial. I hope it is useful to you.

• Sorry, but GM:S works a whole lot differently. – DeleteMe Jul 22 '14 at 6:11
• It can be scripted? If it can, then the underlying concepts are the same, whether you use a different programming language. – angarg12 Jul 22 '14 at 6:46
• But your function are totally different. Also, yours work with 3D Code, mine with 2D. I don't even know what trimBoundary does and how to translate that to GMS. – DeleteMe Jul 22 '14 at 9:23
• My code works on 3D but the z is always 0 so it is effectively 2D. The Clamp function trims a value between a minimum and maximum. Still, I have added another, more generalized answer that explain the abstract terms instead of concrete examples. I hope that one is easier to understand. – angarg12 Jul 22 '14 at 12:01

So you're using Box2D, you should just let the engine handle collisions. (It is generally good to avoid directly setting fixture's position/rotation/speed - just apply forces. iforce2d (https://www.iforce2d.net/b2dtut/) has some awesome related tutorials.)

What you currently are doing is manually setting the position of the ship to its previous position when the ship collides with the room boundaries.

What you should do is just simply NOT do that - just set the fixture for the ship and fixture for the room boundary (optimally an edge shape), and set them to collide.

If you don't know how to make two objects collide, you can achieve this just by creating a collision event (which may be empty if you want - just put a comment in there to prevent the event to be erased automatically) in one of those objects with the other object... like this :

This will cause object 'p_character' to collide with another object 'p_fixture'.

I've just had this same problem, and my step-by-step fix was this:

• Make a new Object to own the collisions. Mine was called 'RoomBoundary'
• Make sure the Object's 'Uses Physics' box is NOT checked. (If you check it you'll end up with the default physics properties, which you don't want).
• In that Object, add a 'Create' Event which runs this script:

  // Excuse magic numbers - I have a 2048x1536 room
var NewBoundary = physics_fixture_create();
physics_fixture_set_chain_shape(NewBoundary, true);  // 'true' closes the loop
physics_fixture_delete(NewBoundary);