Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more

Tech

Physics In GameMaker: Studio - Part 1

Posted by Mark Alexander on 4 October 2014

This week's article is in the form of a mini-tutorial, where we will make a small physics simulation and at the same time discuss some of the issues that people come up against when transitioning from the "traditional" GameMaker: Studio approach to movement and collisions to the physics approach.

Even the most advanced users can be confused when using the GameMaker: Studio physics for the first time, so we'll start this tutorial with probably the most important piece of advice I can give... Forget everything you know about how GameMaker: Studio deals with collisions and movement! When you enable physics in a room, you are changing how everything will interact at a very basic level within GameMaker, and this makes the built in variables like speed and direction obsolete. However, it does enable a whole bunch of specific physics variables which can be used instead.

The other major change that happens when you enable physics is that collisions will be handled automatically for you. With "traditional" GameMaker you would have a collision event and then have some code or action in there to deal with it. But with the physics enabled, the collision will be resolved by GameMaker - with bounce angles and velocities etc... being calculated and applied for you.

So, with that warning out of the way, lets move on and get atrated making a simple physics simulation...

The Physics World

To enable physics, you must first set up the physics world. This is done in the room editor, from the physics tab.

Obviously we need to tick "Room is physics world" (otherwise any physics enabled objects placed in the room will cause errors), and then we set the gravity and the scale for the room. Gravity is calculated as a vector, with the distance and the direction of the vector giving the gravity strength in meters per second and the direction of the gravity pull.

The scale option "pixels to meters" isn't quite so obvious. In the physics simulation, all reactions are based off of "real life" physics, and so the scale of the interaction is important. A 1m cube of lead will not react the same as a 1cm cube of lead, and so we need to let the physics simulation know what scale we are working with. So, here you set how many meters one pixel in the game relates to.

You can leave the default values for this tab and close the room editor for now. You should also quickly make some sprites to use for this example. You'll need two block sprites (one for the floor and one to be a block), a circle sprite and a triangle sprite. They can be any size you want, but for the sake of consistency, keep them around the 32x32px size, as that's what was used to make the tutorial file (available at the end of this article).

Physics Objects

We need to define our objects now, starting with a couple of parent objects. These won't have any physics properties themselves, and will only be used to "group" collisions. Now, as stated at the start of this article, with physics enabled objects will react to collisions automatically, but we still have to tell the physics simulation which objects we want to collide. So to do that we need to give them a collision event, although we add no code to it, just a simple comment to tell the physics that these instances should interact.

Make two objects called "obj_StaticParent" and "obj_DynamicParent". Then add a collision event in both with themselves and each other so that they look like this:

You will see that we have also added an Outside Room event to the Dynamic parent. In there we put an instance destroy action so that if any instance is not in the room it is removed.

Why do we have two parents? Well, in the physics simulation you have three types of object: Static, dynamic and kinematic. Each one has slightly different properties and will behave in a different way:

  • Static - A static body is one that does not react to any external force, which means that it is unaffected by gravity or collisions and will remain immobile in the position that it is placed within the room unless explicitly moved through code. Think of the "ground" blocks you would place in a platformer game, for example. In a physics world they would be classed as static.
  • Dynamic - A dynamic body is one that participates in the full physics simulation and it will react to any forces applied to, like gravity or when in a collision. Anything that moves and reacts to other instances in a game would normally be dynamic.
  • Kinematic - A kinematic body is a sort of mix between static and dynamic. It is an instance that has been flagged as static, but then set in motion through code by setting it's speed directly (not through forces). If you think of a platformer game again, then you would make any moving platforms kinematic so that they don't rotate or react to forces, but they do still move.

For this basic physics simulation we will need four physics enabled bodies: one that is static for the "floor", and three dynamic ones, so go ahead and create these four objects now and give each one an appropriate sprite from those we made earlier.

You need to set the base object to have the "obj_StaticParent" as it's parent, and the other three objects should be children of "obj_DynamicParent" to ensure that the collisions are resolved correctly. We can now move on and define the fixtures for the objects.

Fixtures

Okay, we have our physics enabled room and our objects, but we haven't actually given our objects any physical properties yet, have we? We need to tell GameMaker what properties the physics body will have, which will determine how it interacts with other physics bodies in the game. This is done by defining the fixture.

You define a fixture in two parts, the first being the form it should have and the second being its properties. We can do this directly from the object editor itself or from code, but either way what happens is you define the fixture and then it is bound to the instance for it to use when created in the room. This may seem confusing, so we'll just continue and add a fixture to an object and explain along the way.

Open the object "obj_Base" and click the "Uses Physics" flag. This will expand the object properties window with a number of extra options, shown below:

The first thing to set is the "collision shape". This is where we define the form of the fixture that is to be bound to the object. This is like the collision mask that is assigned when you create a normal object, but with physics enabled that mask is not used, and instead collisions are calculated using the collision shape we define. In this case we want a "box" shape, so mark that now.

You will need to click the "Modify Collision Shape" button too, as you need to make sure the fixture is the correct size for the sprite, so click that to open the Fixture Editor. This editor works the same as the Path Editor and permits you to move the points of the edge of the fixture to fit the sprite being used (or any other form that you require... remember the fixture is independent of the sprite!).

Click "OK" when ready, and with the form now defined, it's time to set the fixture properties. As this object is static, we need to tell the physics simulation to treat it as such, and that is done by setting the density to 0. In real life an object with 0 density isn't possible, so this is the GameMaker way of flagging a fixture as being static. I'll quickly list the rest of the properties here now, although for this object you can leave them as their default values (except density):

  • Density: The density of something is defined as its mass per unit volume, which basically means how much mass is crammed into the space it takes up in the world.
  • Restitution: Restitution is really a way of saying how "bouncy" the fixture is. This setting will affect how much an object "bounces" when it collides with other objects and is co-dependant on other forces that act on the instance like gravity and friction.
  • Collision Group: The collision group can be used to force GameMaker to treat collisions in specific ways.
  • Linear Damping: Damping is used to reduce the physics world velocity of an instance as it moves over time (like air resistence).
  • Angular Damping: As above, only instead of for velocity of movement, this sets the slow down rate for the angular velocity.
  • Friction: Friction sets the loss of momentum caused by the collision of two instances with fixtures bound to them. The lower the value, the easier it is for a colliding instance will "slide" off

You can find a more complete explanation of each of these properties from the manual, so I won't go into too much depth on them here, except where required for the example.

Close the base object now, and open the object "obj_Block". This is our first dynamic object and you should flag it as using physics and adjust the box fixture shape to suit the sprite. The default values are fine here too, with the density set to 0.5, so close the object once you've enabled physics and open the object "obj_Circle".

Again, click the "Uses physics", only now set the collision shape to "Circle". When you edit the collision shape now, you will see that it is no longer a fixture with 4 corner points, but rather a fixture with five points, one marking the center of the fixture and the others marking the radius. Set these to suit your sprite and click "OK". In the properties, set the density to 0.1, and set the restitution to 0.8. We do this because we want it to be lighter than the block fixture and bounce on contact with other fixtures.

For our final object, the triangle, we need to create a polygon fixture. This is a fixture that we define explicitly the points for, and in a very specific way. A polygon fixture has a minimum of 3 points and a maximum of 8 points and it cannot be concave. This is important to note as to make concave shapes you need to bind multiple fixtures which can only be done through code (and we'll cover it in the next tech blog in this series). So, enable physics for this object, and select the "Shape" option for the collision shape. Now when you click the Modify Collision Shape button, you can add and remove points to create your fixture. With that done, set the fixture properties to have a high density and a high linear damping, but a low restitution so it behaves slightly differently from the previous objects.

Testing

We are almost ready to test these objects and see how they react to each other, but before we can we need to make a controller object, so make a new object and call it "obj_Control". Give it an Alarm[0] event with a comment, like "Spawn Timer" or something. This is simply to limit the number of instances of our physics objects spawned. Now add a Step Event with the following:

if (mouse_check_button(mb_left) && (alarm[0] < 0))
{
instance_create(mouse_x, mouse_y, choose(obj_Block, obj_Circle, obj_Triangle));
alarm[0] = 5;
}

Place this object in the room we created at the start, along with a number of the static "obj_Base" objects. Now run the game! If all has gone correctly you should see something like this:

Congratulations! You've just created your first physics simulation in GameMaker: Studio!

Summary

To round off this article, let's just run through some of the important points:

  1. When physics is enabled, all collisions and movement are governed by the special physics variables and functions, not the normal ones.

  2. Physics bodies can be defined by one of three types: static, dynamic or kinematic.

  3. For physics bodies to collide, the instance that has physics enabled must have a collision event, even if that event only has a comment.

  4. An object is physics enabled when it has a fixture bound to it.

  5. A fixture is a combination of a collision shape and basic physical properties.

Hopefully with this article you can see that basic physics is quite easy to set up and start working with. However you'll notice that appart from creating the objects themselves, there is no other interaction in the example. For that we need to start using the dedicated physics functions through the code editor, and we'll be covering that along with a few other more complex themes in the next part.

You can download a GMZ for this tech blog showing the finished example from here.

 

 

Back to Top