• 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!

SOLVED Player mask gets stuck inside wall

Ham

Member
So I'm making a top down dungeon crawler. So far, the player moves with WASD and aim with the mouse pointer, but because my mask is a rectangle and the image angle of the player is set to point_direction(x,y,mouse_x,mouse_y) everytime I point in a direction that isn't 0, 90, 180 or 270, and collide with the wall, the player gets stuck. Are there any easy solutions to this problem?
 

Mk.2

Member
In the create event, make a new variable which will store the player's rotation. Use this variable instead of image_angle. In the draw event, use the function draw_sprite_ext and use the variable you made for the rotation argument.
 
To explain a little more, rotating the image_angle of the instance also rotates it's collision mask. This means if you are flush against a wall and then rotate, the collision mask rotates INTO the wall (a little like this if you pretend the player is | and the wall is O: O| rotates into Ø). You could use some looping logic to push the player away if their mask is inside the wall, but that often feels weird for the player (getting physically moved in a direction when they are only meant to be rotating on the spot) so it's usually better to do exactly what @Mk.2 said and just use a separate variable for the angle of the player sprite. This means image_angle always remains at a constant value and the mask does not rotate at all.
 

Ham

Member
In the create event, make a new variable which will store the player's rotation. Use this variable instead of image_angle. In the draw event, use the function draw_sprite_ext and use the variable you made for the rotation argument.
Thank you! It works really smoothly now, I never would have thought of this
 

Ham

Member
To explain a little more, rotating the image_angle of the instance also rotates it's collision mask. This means if you are flush against a wall and then rotate, the collision mask rotates INTO the wall (a little like this if you pretend the player is | and the wall is O: O| rotates into Ø). You could use some looping logic to push the player away if their mask is inside the wall, but that often feels weird for the player (getting physically moved in a direction when they are only meant to be rotating on the spot) so it's usually better to do exactly what @Mk.2 said and just use a separate variable for the angle of the player sprite. This means image_angle always remains at a constant value and the mask does not rotate at all.
Thanks for the explanation! It really helped me understand what was going on.
 
I have a similar issue, except no matter where i place the variable to store point_direction i get a result that doesnt work.

For example:

If i place the variable in the create event like so:

--- create event ---

facing = point_direction(x, y, mouse_x, mouse_y);

---------------------
and in the draw event have:

--- Draw Event ---

draw_self();
draw_sprite_ext(sSprite, 0, x, y, 1, 1, facing, c_white, 1);

---------------------

i get this result:

tdrotate1.JPG

... a rotating sprite on top of a non-rotating sprite. I get it doesn't rotate as the create event doesn't update after creation so where ever my mouse points at the start is where the player points and is stuck there.

If i move the variable from the create event to the draw event the top sprite rotates towards the mouse but I still have the sprite underneath. Anything i do in the step event, ie, shoot a bullet, happens to the bottom sprite and not the rotating sprite, like so...

tdrotate3.JPG

If i remove the variable and drop in image_angle it draws and works flawlessly, as below, albeit gets stuck in walls on rotation as known.

tdrotate4.JPG
 

Ham

Member
I have a similar issue, except no matter where i place the variable to store point_direction i get a result that doesnt work.

For example:

If i place the variable in the create event like so:

--- create event ---

facing = point_direction(x, y, mouse_x, mouse_y);

---------------------
and in the draw event have:

--- Draw Event ---

draw_self();
draw_sprite_ext(sSprite, 0, x, y, 1, 1, facing, c_white, 1);

---------------------

i get this result:

View attachment 33231

... a rotating sprite on top of a non-rotating sprite. I get it doesn't rotate as the create event doesn't update after creation so where ever my mouse points at the start is where the player points and is stuck there.

If i move the variable from the create event to the draw event the top sprite rotates towards the mouse but I still have the sprite underneath. Anything i do in the step event, ie, shoot a bullet, happens to the bottom sprite and not the rotating sprite, like so...

View attachment 33232

If i remove the variable and drop in image_angle it draws and works flawlessly, as below, albeit gets stuck in walls on rotation as known.

View attachment 33233
You should know the draw event also runs at every frame, just like the step event, from top to bottom, so basically what you've done is tell the game to draw the player and then draw another Sprite of the player again.

The fix is simple, just move the facing = point_direction to step and then in the draw event remove the draw_self(); this should work, hopefully
 
You should know the draw event also runs at every frame, just like the step event, from top to bottom, so basically what you've done is tell the game to draw the player and then draw another Sprite of the player again.

The fix is simple, just move the facing = point_direction to step and then in the draw event remove the draw_self(); this should work, hopefully
I had that before and the it didnt work... heres where i shake my head... i forgot to update everything that was using image_angle to the new variable! SMH... thanks...
 
Top