Help with collision system

C

ChrisSor54

Guest
Ok, so this is a bit of an advanced request for me, but I feel like I'm on the verge of a solution. I'm trying to make a collision system for my game, but I don't want a basic "if player were to move into collision, don't" type system because it doesn't fully work with what I'm trying to do. At first, my system was this:

///@function collision_bounce()
///@description Checks for collision with objCollision and "bounces" player to nearest available space


function collision_bounce()
{
if place_meeting(x,y,objCollision)
{
for(var i = 0; !place_empty(x,y); i += 1; )
{
newY = y;
newX = x;
newY -= i; if place_empty(newX,newY) {x = newX; y = newY; continue;} else {newY = y;}
newY += i; if place_empty(newX,newY) {x = newX; y = newY; continue;} else {newY = y;}
newX -= i; if place_empty(newX,newY) {x = newX; y = newY; continue;} else {newX = x;}
newX += i; if place_empty(newX,newY) {x = newX; y = newY; continue;} else {newX = x;}
newY -= i; newY -= i; if place_empty(newX,newY) {x = newX; y = newY; continue;} else {newY = y; newX = x;}
newY += i; newX += i; if place_empty(newX,newY) {x = newX; y = newY; continue;} else {newY = y; newX = x;}
newY -= i; newX += i; if place_empty(newX,newY) {x = newX; y = newY; continue;} else {newY = y; newX = x;}
newY += i; newX -= i; if place_empty(newX,newY) {x = newX; y = newY; continue;} else {newY = y; newX = x;}

}
}
}

While this system works, there are 2 main flaws. The first is that it can only check cardinal directions, i.e. North, South, NorthWest, SouthEast, etc, which would normally work fine enough (I don't really expect the player to be clipping through collisions much anyway which is where this would matter), but a bug I've noticed is that since it prioritizes certain directions by checking them before others, I run into situations where if the player runs into a corner they just clip through the wall. I know this is tied to which one is checked first, because by switching the order around the corner where this happens changes, but I don't understand the clipping issue.
My goal is to maybe try and fix this by instead using a different system. My idea would be to, when a collision was detected, draw a small circle around the player and check that circle for any open areas. If none were detected, the circles radius would increase by 1, and it would check again, until it found an available area. I'm still somewhat a noob at this as I've only been working with GML for like 2 weeks and it's my first programming language. Any help on what functions I can use to build this system? Thank you.
 
C

ChrisSor54

Guest
It seems a lot more sensible to figure out in which direction the objCollision is and then move the other way.
That totally works for basic collisions, and it's the current fix I'm using in conjunction with this script to solve the little bug I had, but it's not the point of the script. While my goal is to make it a totally independent all-encompassing collision system, it's main purpose is to function as a collision failsafe if the player gets stuck in a wall. In my game, the player is able to enter a "crawl" state, and in doing so the bounding box for the character increases depending on which direction they're crawling. One issue is that because this increase isn't directional, if they enter the crawl state while already adjacent to a collision object, they'll clip inside of it as the bounding box increases. With this system, instead of clipping into the wall, the player is "bounced" away from it to accommodate for the increased collision box. If I went with your more simple solution, the game wouldn't know where the player was before unless I kept track of their coordinates a few frames before, but I don't like having to work around that. For most cases, the distance is only a few pixels, so the restriction to cardinal movement isn't really a problem, but I wanted to build this system to function for any game where a character might clip into walls, so my goal is to make it more than just "good enough".
 

Tyg

Member
Just a suggestion how about ray-casting before you hit the wall
this can be done with point_distance
 
Top