• 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 [Solved] How to get unstuck while in collision objects?

yashamatt

Member
So I have a beginner-style collision code set up and I either want to improve it to avoid bugs or develop some sort of work-around so that if bugs occur the player isn't perpetually stuck in a collision object. I kind of need some help brainstorming a solution.

Due to dealing with a scope that's slightly larger than my ability to code I manage to get my character stuck in my collision objects, though very rarely (I pretty much have to try to clip in on purpose), but still more often than I feel a decent game should allow (eg for reference it does it more often than release-date Skyrim).

I remember playing some games where if you manage to clip collision objects and get stuck the player gets pushed slowly out of the object towards the edge closest to the player object's origin. This would be a pretty nice solution but I'm not exactly sure how I would go about doing it.

I have also looked into the collision_line functions and want to convert my current collision code to use these because I've heard they're better to use but I still haven't figured it out properly yet, and clipping may still occur (right?).

I don't think it's a problem with masks because I use the one default mask between sprites/states.

the game is a 2d platformer.

my current code is:

if !place_meeting(x + xSpeed, y, par_solid){
x += xSpeed;
}
if place_meeting(x + xSpeed, y, par_solid){
while !place_meeting(x + sign(xSpeed), y, par_solid){
x += sign(xSpeed);
}
xSpeed = 0;
}

if !place_meeting(x, y + ySpeed, par_solid){
y += ySpeed;
}
if place_meeting(x, y + ySpeed, par_solid){
while !place_meeting(x, y + sign(ySpeed), par_solid){
y += sign(ySpeed);
}
ySpeed = 0;
}
 

Relic

Member
Your code is pretty much identical to the popular tutorials and unless there is a typo in there, should be pixel perfect.

Have anything else that could affect the collisions? Platforms that move? Flipping the sprite image (which also flips the mask) without having an origin in the centre of the mask?
 
B

Bayesian

Guest
This is just a very basic simple method to move outside colliding objects, be sure to thoroughly test it for compatibility

Make a parent object and make your walls floor and player children of it. Then do something like this inside a collision event with that parent:

Code:
if place_meeting(x, y, all)
   {
   var pdir;
   pdir = point_direction(other.x, other.y, x, y);
   move_outside_all(pdir, 1);
   }
}
Be sure to read the Docs on move_outside_all
https://docs.yoyogames.com/source/d...and collisions/movement/move_outside_all.html
 
S

spoonsinbunnies

Guest
your current code actually can run at 1.9 hspeed or yspeed. it could jump the full distance, then be less than the distance from a solid and jump any amount less than the full amount side afterward. I like to use something like this instead personally
Code:
repeat hSpeed
{
!place_meeting(x+sign(hSpeed), y, par_solid)         
x+=sign(xSpeed)
}
repeat vSpeed
{
!place_meeting(x, y + sign(ySpeed), par_solid)
y+=sign(ySpeed)
}
 

Relic

Member
That’s true. You can turn the second “if place meeting” check into an “else if placemeeting” check for both x and y directions.

Doesn’t explain the stick in platforms though.
 
S

spoonsinbunnies

Guest
That’s true. You can turn the second “if place meeting” check into an “else if placemeeting” check for both x and y directions.

Doesn’t explain the stick in platforms though.
this is true, tbh Id have to assume a moving platform, a nonsquare or round collision mask, or theres a bug I have trouble explaining in words, but essentially xspeed switches but the direction traveled dosent or vice versa, those are generally the 3 things that cause that but I didn't have enough information to make a guess of which of the 3
 

yashamatt

Member
Your code is pretty much identical to the popular tutorials and unless there is a typo in there, should be pixel perfect.

Have anything else that could affect the collisions? Platforms that move? Flipping the sprite image (which also flips the mask) without having an origin in the centre of the mask?
Your code is pretty much identical to the popular tutorials and unless there is a typo in there, should be pixel perfect.

Have anything else that could affect the collisions? Platforms that move? Flipping the sprite image (which also flips the mask) without having an origin in the centre of the mask?
Yeah masks/sprites are all centred properly and I have the object use the one mask regardless sprite so im pretty convinced it's not an issue. I think it might be an issue with using floats in some of the movement but i'm just guessing.
 

yashamatt

Member
This is just a very basic simple method to move outside colliding objects, be sure to thoroughly test it for compatibility

Make a parent object and make your walls floor and player children of it. Then do something like this inside a collision event with that parent:

thanks i'll give this a try
 
S

spoonsinbunnies

Guest
can I see your inputs code to rule out the third thing I was talking about? I worded it poorly but I should be able to check for it that way. Also a snapshot of your mask would help
 

yashamatt

Member
@spoonsinbunnies
sorry for the late reply.
Code:
//horizontal movement
if xInput != 0 {
    xSpeed += xInput * accel;
    xSpeed = clamp(xSpeed, -maxRunSpeed, maxRunSpeed);
} else {
    xSpeed = lerp(xSpeed, 0, frict);
}
//horizontal collisions go here

//gravity
if ySpeed < maxFallSpeed{
    ySpeed += weight;
}
//vertical collisions go here
seems to only happen on/near the corners of stationary collision objects.

@Bayesian
thanks, works like a charm, I didn't know this function existed, and it's perfect should any shenanigans occur with my janky spaghetti code.
 

yashamatt

Member
Late but I found a better solution.

in the collision object parent (eg obj_solid etc) create a collision event with whatever you dont want to overlap
Code:
var _x = x - sprite_get_xoffset(sprite_index) + sprite_width / 2;
var _y = y - sprite_get_yoffset(sprite_index) + sprite_height / 2;

var dir= point_direction(_x, _y, x, y);   

with other 
{
    move_outside_solid(dir, 5);
}
 
Top