Maarten Baert's website

Game Maker / C++ projects

Home Model Creator ExtremePhysics Game Maker DLLs   Recent comments Search

Last modified: Sat, 5 Mar 2011
Refresh

Getting started


What is ExtremePhysics?

ExtremePhysics is a 2D rigid body simulation engine designed for Game Maker. The DLL is written in C++.

ExtremePhysics classes

ExtremePhysics uses a number of classes (types of resources):

  • World: This class connects the other classes. You can create multiple worlds but most of the time one world is all you need.

  • Polygon: Polygons are used to define the vertices of polygon shapes.

  • Body: A body is the equivalent an object in Game Maker. Usually every object in Game Maker is associated with one body.

  • Shape: Shapes are used to define the shape of a body. There are three types of shapes: box shapes, circle shapes and polygon shapes. One body can consist of multiple shapes.

  • Force: Forces can be added to bodies to simulate some effects, e.g. a rocket engine.

  • Contact: This is a special class. You can't create or destroy contacts, because contacts are created and destroyed automatically by ExtremePhysics during the simulation when different shapes collide. Contacts can be used to detect collisions.

  • Joints: Joints are used to connect bodies. There are multiple types of joints.

  • View: Views can be used to speed up the simulation for games that use views. Parts of the world that are out of view can be put to sleep to save processing time.

This image shows how the classes are connected:

Image: class-connections.png

Hint

All angles in ExtremePhysics are in radians.

Initializing ExtremePhysics

If you are using the DLL (instead of the extension), you have to initialize ExtremePhysics before you can use it. This isn't very hard:

// If the name of the DLL file is ExtremePhysics.dll,
// this should work:
extremephysics_init();

// If the DLL is not in the working directory,
// you can use this instead:
extremephysics_init("path/to/ExtremePhysics.dll");

Note that the game start event is executed after the create event, therefore it's a good idea to create an empty room (room_gamestart) with one object (obj_gamestart) that executes this code before going to the next room, to make sure this code is executed before anything else.

If you forget to initialize the DLL, you will get an error message when you try to use the scripts ("undefined variable global.define_ep_functionname").

Creating a world

Creating a world is easy:

global.world = ep_world_create();

After creating the world, you should change the settings of the world:

ep_world_set_settings(global.world,1,20,10,0.1,0.5,0,0.5,1);

I will explain the meaning of this code in a separate tutorial.

Creating a static body

There are two kinds of bodies: static and dynamic. Static bodies can move, but their movement isn't influenced by other bodies. The movement of dynamic bodies can be influenced by other bodies (even static bodies). Static bodies are used for things that can not be moved by other bodies (e.g. the ground, walls, platforms that move at a fixed speed).

I will show you how to create a simple static box. First you have to create the body:

body = ep_body_create_static(global.world);
// global.world: the id of the world you created.

However, without any shapes the body isn't very useful. The next step is to add a box shape:

shape1 = ep_shape_create_box(global.world,body,32,32,0,0,0,1);
// global.world: the id of the world.
// body: the id of the body you created.
// 32,32: the size of the box.
// 0,0,0: the relative coordinates of the shape (x,y,rot).
// 1: the density of the box (not used for static bodies).

This code will create a static box, but the box won't collide with anything. The collision system ExtremePhysics uses takes three values: collision mask 1, collision mask 2 and group. Collision mask 1 and collision mask 2 are 32-bit unsigned integers. Collision mask 1 stores the layers the shape belongs to, collision mask 2 stores the layers the shape should collide with. Every bit is one layer, so you can use up to 32 layers. If collision mask 1 matches collision mask 2 or collision mask 2 matches collision mask 1, the bodies will collide. But if they are in the same group (not group 0), they will never collide.

// pseudo-code
if (body1.mask1 & body2.mask2 != 0 or body1.mask2 & body2.mask1 != 0) and (body1.group == 0 or body1.group != body2.group) {
    // collision
} else {
    // no collision
}

Groups are useful if your game uses lots of small groups of bodies that can't collide, like cars (the wheels shouldn't collide with the car, otherwise they can't overlap).

ep_shape_set_collision(global.world,body,shape1,1,1,0);
// 1: collision mask 1 (binary 00000000 00000000 00000000 00000001).
// 1: collision mask 2 (binary 00000000 00000000 00000000 00000001).
// 0: group (0 means no group).

The next step is to change the material of the box:

ep_shape_set_material(global.world,body,shape1,0.5,0.4,0,0);
// 0.5: coefficient of restitution.
// 0.4: friction.
// 0: normal surface velocity.
// 0: tangential surface velocity.

Finally the box is moved to the correct position:

ep_body_set_position(global.world,body,x,y,degtorad(image_angle));
// x: x coordinate of the body.
// y: y coordinate of the body.
// degtorad(image_angle): rotation of the body, in radians.

Creating a dynamic body

Creating dynamic bodies is almost the same as creating static bodies. There is one extra argument for dynamic bodies: norotation. If norotation is true, the rotation of the body will not be influenced by other bodies (because the moment of inertia of the body is infinite).

body = ep_body_create_dynamic(global.world,false);
// false: this body can rotate.

You have to set the center of mass, mass and moment of inertia of the body before you can use it. The easiest way to do this is calling ep_body_calculate_mass. This function will calculate the center of mass, mass and moment of inertia of the body based on the shapes you have added to the body.

// call this function after adding the shapes:
ep_body_calculate_mass(global.world,body);

Circle shapes

You can create circle shapes in the same way you create box shapes:

shape1 = ep_shape_create_circle(global.world,body,32,0,0,0,1);
// 32: the radius of the circle.
// 0,0,0: the relative coordinates of the shape (x,y,rot).
// 1: the density of the circle (not used for static bodies).

Polygon shapes

Creating polygon shapes is more complicated, because you have to create a polygon first. A polygon can be used by multiple bodies, so usually you can create all polygons immediately after creating the world.

global.poly_triangle1 = ep_polygon_create(global.world,3);
// 3: number of vertices.
ep_polygon_set_vertex(global.world,global.poly_triangle1,0,-10,-10);
// 0: first vertex.
// -10,-10: coordinates of the vertex.
ep_polygon_set_vertex(global.world,global.poly_triangle1,1,+10,+10);
// 1: second vertex.
// +10,+10: coordinates of the vertex.
ep_polygon_set_vertex(global.world,global.poly_triangle1,2,-10,+10);
// 2: third vertex.
// -10,+10: coordinates of the vertex.
ep_polygon_initialize(global.world,global.poly_triangle1);

There are two things you have to take in mind:

  • Vertices have to be declared in clockwise order (in a left-handed coordinate system).

  • All polygons have to be convex. If a body is concave you have to create multiple convex polygons. You can use multipolygons to accomplish that.

shape1 = ep_shape_create_polygon(global.world,body,global.poly_triangle1,0,0,0,1);
// global.poly_triangle1: the id of the polygon.
// 0,0,0: the relative coordinates of the shape (x,y,rot).
// 1: the density of the polygon (not used for static bodies).
Warning

You can't destroy a polygon if it's still in use.

Simulating

You have to call ep_world_update_contacts and ep_world_simulate_step to simulate one step. Usually this is done in the end step event of the controller.

ep_world_update_contacts(global.world);
ep_world_simulate_step(global.world);

After simulating a step you have to update the position and orientation of the objects in Game Maker to see the results of the simulation.

x = ep_body_get_x(global.world,body);
y = ep_body_get_y(global.world,body);
image_angle = radtodeg(ep_body_get_rot(global.world,body));

Destroying ExtremePhysics resources

When you destroy an object in Game Maker, you have to destroy the body too:

ep_body_destroy(global.world,body);

Don't forget to destroy the world when the player leaves the room:

// room end event
ep_world_destroy(global.world)
Hint

When a world is destroyed, all polygons, bodies, contacts, joints and views that belong to the world are destroyed. When a body is destroyed, all shapes and forces that belong to the body are destroyed.

Good luck!


Comments

N1k10s

Comment #1: Sat, 5 Jun 2010, 9:47 (GMT+1, DST)

Quote


I am simply amazed. Thank you so much for these tutorials. I shall stop by every now and then to see what might have been added. I would say that I am an intermediate when it comes to programing and that this is far beyond me. However, your tutorials make perfect sense.

One question: Are these codes free to use in other programs? It is exactly what I need for a game of mine created with GM.

Maarten Baert

Administrator

Comment #2: Wed, 23 Jun 2010, 16:37 (GMT+1, DST)

Quote


Quote: N1k10s

I am simply amazed. Thank you so much for these tutorials. I shall stop by every now and then to see what might have been added. I would say that I am an intermediate when it comes to programing and that this is far beyond me. However, your tutorials make perfect sense.

One question: Are these codes free to use in other programs? It is exactly what I need for a game of mine created with GM.

The code in this tutorial is of course completely free. The source code of the DLL is distributed under the terms of the GNU Lesser General Public License, which means you can use it in any project, but if you start making changes to the source code you have to make those changes public under the same or a similar license. If you're just using the DLL or the extension in GM, then it is "free to use, also for commercial games".

Cklester

Comment #3: Sun, 26 Sep 2010, 22:21 (GMT+1, DST)

Quote


Maarten, could you provide me with an example room of a soccer ball being dropped at an angle from a height and bouncing on a solid floor until it stops? I think that would go a long way in helping me understand how to set up the world and how to attach a sprite to a physics object.

Thank you!

Edit: I'm using GMP8

Last modified: Sun, 26 Sep 2010, 22:22 (GMT+1, DST)

Maarten Baert

Administrator

Comment #4: Tue, 28 Sep 2010, 23:56 (GMT+1, DST)

Quote


Quote: Cklester

Maarten, could you provide me with an example room of a soccer ball being dropped at an angle from a height and bouncing on a solid floor until it stops? I think that would go a long way in helping me understand how to set up the world and how to attach a sprite to a physics object.

Thank you!

Edit: I'm using GMP8

I've added a simple platform example yesterday, it should give you a good idea where to start :).

Cklester

Comment #5: Wed, 29 Sep 2010, 2:30 (GMT+1, DST)

Quote


Cool! Thanks, Maarten. I'll check it out.

Tbone

Comment #6: Thu, 7 Oct 2010, 5:32 (GMT+1, DST)

Quote


I was trying to create a simple dynamic ball to fall down onto the static blocks, but this didn't work out well. Can anyone figure out the problem please. I really would like to learn how to use this. The link is here http://www.speedyshare.com/files/24599850/Try_at_Extreme_Physics.gmk

-Thanks in Advance : )

Last modified: Fri, 8 Oct 2010, 17:35 (GMT+1, DST)

Maarten Baert

Administrator

Comment #7: Sat, 16 Oct 2010, 15:12 (GMT+1, DST)

Quote


Quote: Tbone

I was trying to create a simple dynamic ball to fall down onto the static blocks, but this didn't work out well. Can anyone figure out the problem please. I really would like to learn how to use this. The link is here http://www.speedyshare.com/files/24599850/Try_at_Extreme_Physics.gmk

-Thanks in Advance : )

  • endstep(); should be in the end step event of the controller, not in the end step event of the ball.

  • You should use ep_body_set_gravity if you want the ball to fall.

It should work now.

Tbone

Comment #8: Sat, 16 Oct 2010, 16:21 (GMT+1, DST)

Quote


Ohh...Duh! Thanks Maarten Baert. :D

I would use ep_body_set_gravity like this right?

ep_body_set_gravity(global.world,body,0,y+100);

Last modified: Sun, 17 Oct 2010, 10:12 (GMT+1, DST)

Ross93

Comment #9: Wed, 2 Mar 2011, 2:50 (GMT+1, DST)

Quote


Hey there

I've been using this physics engine and I love it!

I've written a bit of code which can easily turn this into a top-down / birds-eye view physics engine...

xx=ep_body_get_xvel_center(global.world, argument0)
yy=ep_body_get_yvel_center(global.world, argument0)
arot=ep_body_get_rotvel(global.world, argument0)
if xx !=0 then xx*=floor_friction
if yy !=0 then yy*=floor_friction
if arot != 0 then arot*=floor_friction
ep_body_set_velocity_center(global.world, argument0, xx,yy,arot)

where floor_friction is a decimal number between 0 and 1 (1 being no friction and 0 being lots of friction)

If all your bodies have 0 gravity, then if you put this in the step event you will have a working top-down physics engine. I know this is probably elementary stuff but it might help some people :)

Cheers
Ross

Maanu40

Comment #10: Wed, 2 Mar 2011, 15:51 (GMT+1, DST)

Quote


Help!

When I give the code:

ep_world_set_settings(global.world,1,20,10,0.1,0.5,0.1,0.5,1);

In the Create-event, the code editor says that there is a wrong number of arguments in this function. :S Please answer!

Maanu40

Joona

Comment #11: Fri, 4 Mar 2011, 16:00 (GMT+1, DST)

Quote


Quote: Maarten Baert
Quote: Tbone

I was trying to create a simple dynamic ball to fall down onto the static blocks, but this didn't work out well. Can anyone figure out the problem please. I really would like to learn how to use this. The link is here http://www.speedyshare.com/files/24599850/Try_at_Extreme_Physics.gmk

-Thanks in Advance : )

  • endstep(); should be in the end step event of the controller, not in the end step event of the ball.

  • You should use ep_body_set_gravity if you want the ball to fall.

It should work now.

Hi
I tried to combine http://www.yoyogames.com/games/54283-chain-example and your platform_example, but if I put End Step event to ball_object , I am no longer able to move it and without it, the collision does not work with obj_crate.
I wonder what I have to do with it?

Maarten Baert

Administrator

Comment #12: Sat, 5 Mar 2011, 18:39 (GMT+1, DST)

Quote


Quote: Ross93

Hey there

I've been using this physics engine and I love it!

I've written a bit of code which can easily turn this into a top-down / birds-eye view physics engine...

[...]

where floor_friction is a decimal number between 0 and 1 (1 being no friction and 0 being lots of friction)

If all your bodies have 0 gravity, then if you put this in the step event you will have a working top-down physics engine. I know this is probably elementary stuff but it might help some people :)

Cheers
Ross

You can also use ep_body_set_damping in the create event, that function does exactly the same :).

Quote: Maanu40

Help!

When I give the code:

ep_world_set_settings(global.world,1,20,10,0.1,0.5,0.1,0.5,1);

In the Create-event, the code editor says that there is a wrong number of arguments in this function. :S Please answer!

Maanu40

That code works for me. Are you sure you're using the latest version (2.2)?

Quote: Joona

Hi
I tried to combine http://www.yoyogames.com/games/54283-chain-example and your platform_example, but if I put End Step event to ball_object , I am no longer able to move it and without it, the collision does not work with obj_crate.
I wonder what I have to do with it?

That example uses GM's movement system (direction, speed, gravity, ...), which is not compatible with ExtremePhysics. You should replace them by ExtremePhysics functions, e.g. ep_body_apply_impulse to move towards the target, ep_body_set_damping to simulate friction, ...

Last modified: Sat, 5 Mar 2011, 19:00 (GMT+1, DST)

Joona

Comment #13: Sat, 5 Mar 2011, 20:45 (GMT+1, DST)

Quote


Quote: Maarten Baert
Quote: Joona

Hi
I tried to combine http://www.yoyogames.com/games/54283-chain-example and your platform_example, but if I put End Step event to ball_object , I am no longer able to move it and without it, the collision does not work with obj_crate.
I wonder what I have to do with it?

That example uses GM's movement system (direction, speed, gravity, ...), which is not compatible with ExtremePhysics. You should replace them by ExtremePhysics functions, e.g. ep_body_apply_impulse to move towards the target, ep_body_set_damping to simulate friction, ...

Ok, thanks, but now I have even bigger problem.
I am new with Game Maker and normal movements are still hard to me.
Can you make me an example how these functions works with mouse, if it is possible?

Maarten Baert

Administrator

Comment #14: Tue, 15 Mar 2011, 20:02 (GMT+1, DST)

Quote


Quote: Joona

Ok, thanks, but now I have even bigger problem.
I am new with Game Maker and normal movements are still hard to me.
Can you make me an example how these functions works with mouse, if it is possible?

Well, you have to understand the normal movement system first. Otherwise you won't understand the ExtremePhysics functions either. Did you read the official Game Maker tutorials?

De

Comment #15: Wed, 21 Mar 2012, 9:46 (GMT+1, DST)

Quote


hi,
i don't understand why does a circular object bounce up even when its rolling on a flat surface???
what should i do to prevent that from happening???

Maarten Baert

Administrator

Comment #16: Wed, 28 Mar 2012, 22:02 (GMT+1, DST)

Quote


Quote: De

hi,
i don't understand why does a circular object bounce up even when its rolling on a flat surface???
what should i do to prevent that from happening???

That's probably because the flat surface consists of many separate blocks in your game. You can reduce the effect by using a higher framerate (60 instead of 30) or substeps, i.e. simulating multiple steps per actual frame. The only way to actually eliminate the effect is to use a single shape for the entire surface. Take a look at the 'merging walls' example, if your game is grid-based that should be enough.

Write a comment