• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker How to change collision shape of the using physics object ?

S

Skrininshot

Guest
[fixed]
(sorry for bad english)
In some cases, I need to change an already installed collision shape of one of the objects which using physics, but I do not know how to do it. I tried to figure out the physic fixtures, but I realized that when an object uses physics, it defaults has fixture that you can change in the "Modify collision shape" section which can`t be changed by code
 
Last edited by a moderator:
I believe you can use the following functions to define a new polygon shape:

physics_fixture_set_polygon_shape()
physics_fixture_add_point()

Documentation example:

physics_fixture_set_polygon_shape(fix_Ship);
physics_fixture_add_point(fix_Ship, 0,0);
physics_fixture_add_point(fix_Ship, -40, 100);
physics_fixture_add_point(fix_Ship, 40, 100);
 
S

Skrininshot

Guest
Now the object has several frictions active: the one that is specified in the "Modify collision shape" and the one written in the create of object, and besides, neither this nor this one can be changed:
Code:
//Create

fix = physics_fixture_create
physics_fixture_set_polygon_shape(fix)

physics_fixture_add_point(fix,9,-20)//righttop
physics_fixture_add_point(fix,9,20)//rightbottom
physics_fixture_add_point(fix,-9,20)//leftbottom
physics_fixture_add_point(fix,-9,-20)//lefttop

physics_fixture_set_density(fix,2)
physics_fixture_set_restitution(fix,0.1)
physics_fixture_set_collision_group(fix,0)
physics_fixture_set_linear_damping(fix,0.5)
physics_fixture_set_angular_damping(fix,0.1)
physics_fixture_set_friction(fix,3)
physics_fixture_bind(fix,self)
physics_fixture_delete(fix)

//Step

if keyboard_check_pressed(ord('P'))
{
if a = 0
{
fix = physics_fixture_create
physics_fixture_set_polygon_shape(fix)

physics_fixture_add_point(fix,9,-10)//righttop
physics_fixture_add_point(fix,9,18)//rightbottom
physics_fixture_add_point(fix,-9,18)//leftbottom
physics_fixture_add_point(fix,-9,-10)//lefttop

physics_fixture_delete(fix)
a = 1
}
else
{
fix = physics_fixture_create
physics_fixture_set_polygon_shape(fix

physics_fixture_add_point(fix,9,-20)//righttop
physics_fixture_add_point(fix,9,18)//rightbottom
physics_fixture_add_point(fix,-9,18)//leftbottom
physics_fixture_add_point(fix,-9,-20)//lefttop

physics_fixture_delete(fix)
a = 0
}
}

[/CODE
 
Last edited by a moderator:
You can't change or delete the fixture assigned in the object window's physics pannel, becuase you don't have a handdle to it. So, instead of assigning a fixture in the physics pannel, just do it through code.

physics_fixture_bind will return the id of the fixture that it binds to your instance. You can use that id later on to unbind the fixture with physics_remove_fixture.
 

Karlstens

Member
Similar to how sprites have multiple frames, can Physics Collision Shapes in objects have multiple frames as well? That way, an object could be pre-defined with shapes than can then be called by code.
 

Jezla

Member
Now the object has several frictions active: the one that is specified in the "Modify collision shape" and the one written in the create of object, and besides, neither this nor this one can be changed:
Code:
//Create

fix = physics_fixture_create
physics_fixture_set_polygon_shape(fix)

physics_fixture_add_point(fix,9,-20)//righttop
physics_fixture_add_point(fix,9,20)//rightbottom
physics_fixture_add_point(fix,-9,20)//leftbottom
physics_fixture_add_point(fix,-9,-20)//lefttop

physics_fixture_set_density(fix,2)
physics_fixture_set_restitution(fix,0.1)
physics_fixture_set_collision_group(fix,0)
physics_fixture_set_linear_damping(fix,0.5)
physics_fixture_set_angular_damping(fix,0.1)
physics_fixture_set_friction(fix,3)
physics_fixture_bind(fix,self)
physics_fixture_delete(fix)

//Step

if keyboard_check_pressed(ord('P'))
{
if a = 0
{
fix = physics_fixture_create
physics_fixture_set_polygon_shape(fix)

physics_fixture_add_point(fix,9,-10)//righttop
physics_fixture_add_point(fix,9,18)//rightbottom
physics_fixture_add_point(fix,-9,18)//leftbottom
physics_fixture_add_point(fix,-9,-10)//lefttop

physics_fixture_delete(fix)
a = 1
}
else
{
fix = physics_fixture_create
physics_fixture_set_polygon_shape(fix

physics_fixture_add_point(fix,9,-20)//righttop
physics_fixture_add_point(fix,9,18)//rightbottom
physics_fixture_add_point(fix,-9,18)//leftbottom
physics_fixture_add_point(fix,-9,-20)//lefttop

physics_fixture_delete(fix)
a = 0
}
}

[/CODE

None of the step even fixture code will have any effect. You're creating a fixture and then deleting it every step without binding it to anything.

Firstly, if you want to use the physics system, then start with the tutorials that have recently been published on the blog.

Secondly the proper way to change a collision shape is to remove the bound fixture and bind a new fixture. To do this, you must define your fixtures in code. You must do this because you need to save the ID of the bound fixture in a variable, which cannot be done by setting the collision shape in the object editor. You need to uncheck the "Uses physics" box in the object editor. Then you would have something like this:

Code:
///Create Event
//Define the fixture
var fix = physics_fixture_create();
physics_fixture_set_polygon_shape(fix);
physics_fixture_add_point(fix, 9, -20);
physics_fixture_add_point(fix, 9, 20);
physics_fixture_add_point(fix, -9, 20);
physics_fixture_add_point(fix, -9, -20);
physics_fixture_set_restitution(fix,0.1)
physics_fixture_set_collision_group(fix,0)
physics_fixture_set_linear_damping(fix,0.5)
physics_fixture_set_angular_damping(fix,0.1)
physics_fixture_set_friction(fix,3)
myfix = physics_fixture_bind(fix, id);  //THIS IS IMPORTANT!!!  Store the ID in a variable, you'll need it later.  Also, do not use the self keyword; use id instead!
physics_fixture_delete(fix);

///When you need to change the fixture
//Remove the fixture
physics_remove_fixture(id, myfix);

//Create the new fixture
var fix = physics_fixture_create();
physics_fixture_set_polygon_shape(fix);
physics_fixture_add_point(fix, 9, -18);
physics_fixture_add_point(fix, 9, 18);
physics_fixture_add_point(fix, -9, 18);
physics_fixture_add_point(fix, -9, -18);
physics_fixture_set_restitution(fix,0.1)
physics_fixture_set_collision_group(fix,0)
physics_fixture_set_linear_damping(fix,0.5)
physics_fixture_set_angular_damping(fix,0.1)
physics_fixture_set_friction(fix,3)
myfix = physics_fixture_bind(fix, id);
physics_fixture_delete(fix);
To go back to the original fixture properties, you will have to remove the current fixture and define and bind a new fixture.

Edit: To answer @Karlstens question, I suppose it would be possible when defining fixtures to assign them to a global variable that can be bound to instances as needed, but I wouldn't recommend it. Fixtures take up memory, and you could get memory leaks or performance problems if they're not deleted when they're no longer needed. You'd have to be very careful to make sure that all your un-needed fixtures are deleted in a cleanup event. I'd rather just create them as I need them and the delete them once their bound to instances.
 
Last edited:
Top