[SOLVED]Collision System Help

D

Dogtooth

Guest
I am quite new to Game Maker and have be enjoying it tremendously! But, It seems I have hit my first large bump in the road while working on my collision.

My movement system uses the built-in hspeed and vspeed variables. My goal was to make the ground slippery, to simulate walking on ice. So, what I did was tell the game that when the player presses a key (for instance the right arrow key), it gives them an initial movement speed of 5 in whatever direction I assigned to it (in this case, I would assign it positive five so that the player would move to the right). Then the game would subtract a integer form that number every step until it reached zero, this would create a sliding affect. Using this I was able to create a movement system that works quite well, with little to no issues.

However now that I have moved on to making collisions in the game, (like, "if touch wall, stop" (only if it were that easy)) I have arrived at a plethora of issues. After thinking how I could develop something that feels smooth using my limited knowledge, I came up with his:


Code:
///Crappy collision
// player collision
if place_meeting(x,y,obj_horwallright) && (hspeed < 0)
    {
        hspeed *= 0
    }
if place_meeting(x,y,obj_horwallleft) && (hspeed > 0)
    {
        hspeed *= 0
    }
if place_meeting(x,y,obj_vertwallup) && (vspeed < 0)
    {
        vspeed *= 0
    }
if place_meeting(x,y,obj_vertwalldown) && (vspeed > 0)
    {
        vspeed *= 0
    }
I have created individual objects for each side of the wall.

This collision is almost somewhat acceptable, however there are many issues, for example when I hit a outward facing corner I can get stuck in place, or I may be walking along the edge of a wall and when I go past the end of the wall and decide to turn around, I am restricted from moving back any more.

If you have any suggestions on how I might be able to improve on (or fix) this system, I would greatly appreciate the feedback.
 

The-any-Key

Member
The first thing I would suggest is to use a sprite mask for the moving object. Then when you turn the player you don't get stuck if you are near a wall.

The problem with collisions is that you move x pixels. Ex if hspeed is 10 and the wall is 5 pixels away. The object will be 5 pixels inside the wall.
 
A

Atryue

Guest
I recommend watching Shaun's video on platformer collision.

I prefer his proactive way of handling collisions versus allowing them to happen and trying to compensate after the fact.
Even though you're using the built-in vspeed and hspeed variables, I think you should be able to adopt his code to your project.


This is the best I could adapt his code to yours...

Code:
if (place_meeting(x+hspeed, y, obj_wall)) //If my player is about to horizontally collide with a wall.
{
while(!place_meeting(x+sign(hspeed), y, obj_wall)) //While we're not exactly 1 pixel away from the wall.
{
x += sign(hspeed); //Move 1 pixel in the direction towards the wall.
}
hspeed = 0; //Stop moving horizontally.
}
x += hspeed; //I don't know if you need this or not... Might need to remove.

Truth be told, I haven't used the built-in hspeed and vspeed. I normally use my own variables. So, you might have to tweak the code to make it work.

PS: I personally would make a parent "obj_wall" object and then create children wall objects if you really need them.
 
Last edited by a moderator:
D

Dogtooth

Guest
I recommend watching Shaun's video on platformer collision.

I prefer his proactive way of handling collisions versus allowing them to happen and trying to compensate after the fact.
Even though you're using the built-in vspeed and hspeed variables, I think you should be able to adopt his code to your project.


This is the best I could adapt his code to yours...

Code:
if (place_meeting(x+hspeed, y, obj_wall)) //If my player is about to horizontally collide with a wall.
{
while(!place_meeting(x+sign(hspeed), y, obj_wall)) //While we're not exactly 1 pixel away from the wall.
{
x += sign(hspeed); //Move 1 pixel in the direction towards the wall.
}
hspeed = 0; //Stop moving horizontally.
}
x += hspeed; //I don't know if you need this or not... Might need to remove.

Truth be told, I haven't used the built-in hspeed and vspeed. I normally use my own variables. So, you might have to tweak the code to make it work.

PS: I personally would make a parent "obj_wall" object and then create children wall objects if you really need them.
Wow, I implemented the code, took out the "x += hspeed", and watched the video to add the vertical component of the collision, and it works Great! Better yet, I can now entirely abandon the idea of having multiple objects to act as each side of the wall.

This is what it looks like now:

Code:
if (place_meeting(x+hspeed, y, obj_iceworldwall)) //If my player is about to horizontally collide with a wall.
{
while(!place_meeting(x+sign(hspeed), y, obj_iceworldwall)) //While we're not exactly 1 pixel away from the wall.
{
x += sign(hspeed); //Move 1 pixel in the direction towards the wall.
}
hspeed = 0; //Stop moving horizontally.
}

if (place_meeting(x,y+vspeed, obj_iceworldwall)) //If my player is about to horizontally collide with a wall.
{
while(!place_meeting(x,y+sign(vspeed), obj_iceworldwall)) //While we're not exactly 1 pixel away from the wall.
{
y += sign(vspeed); //Move 1 pixel in the direction towards the wall.
}
vspeed = 0; //Stop moving horizontally.
}
 
D

Dogtooth

Guest
The first thing I would suggest is to use a sprite mask for the moving object. Then when you turn the player you don't get stuck if you are near a wall.

The problem with collisions is that you move x pixels. Ex if hspeed is 10 and the wall is 5 pixels away. The object will be 5 pixels inside the wall.
Ya, I was not quite sure what was going wrong exactly, I figured that I must have been hitting both walls and the same time, thus cancelling out my movement towards the walls in both directions at the same time. Though now, I think that it had more to do with being actually inside the wall, as I would notice my character would go closer or farther from the wall each time I collided with it.
 
Top