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

Horizontal and Vertical Collision No Longer Working After Being Converted to Scripts

Storm1208

Member
I'm working on a finite state machine implementation for a platforming character. I initially coded the character normally (i.e. not using a state machine approach) but am now beginning to convert what I had previously implemented into a state machine format.

To aid in readability, each separate state is it's own script and some of the functionality within them is also being given its own scripts. I took the my horizontal and vertical collision code, placed them in their own scripts, and then called them from within the necessary state scripts. For some reason though, the collisions don't seem to be working now and my player is glitchily phasing through walls.

Here's a snippet of what my scripts look like:

running_state script (is called when the character is in the "running" state):
GML:
// Script assets have changed for v2.3.0 see
// https://help.yoyogames.com/hc/en-us/articles/360005277377 for more information
function running_state(){

//covering horizontal movement
if(right_key - left_key != 0)
{
    image_xscale = sign(hsp); //handling player facing direction
    hsp = acc + hsp_walk * (right_key - left_key);
}
else
{
    //handling gradual deceleration
    if(hsp > 0)
    {
        hsp -= dec_const;
        if(0 + hsp < 0.4)
        {
            hsp = 0;
            my_state = PlayerState.idle;
        }
    }
    else if(hsp < 0)
    {
        hsp +=     dec_const;
        if(0 - hsp < 0.4)
        {
            hsp = 0;
            my_state = PlayerState.idle;
        }
    }
}

//handling acceleration
if(right_key - left_key != 0 && hsp < 0)
{
    if(hsp > sign(hsp) * speed_cap)
    {
        acc += sign(hsp) * acc_const;   
    }
}
else if(right_key - left_key != 0 && hsp > 0)
{
    if(hsp < sign(hsp) * speed_cap)
    {
        acc += sign(hsp) * acc_const;   
    }
}
else if(right_key - left_key == 0)
{
    acc = 0;
}

horizontal_collision();

}
horizontal_collision script (handles horizontal collision):
GML:
// Script assets have changed for v2.3.0 see
// https://help.yoyogames.com/hc/en-us/articles/360005277377 for more information
function horizontal_collision(){
    
//horizontal collision//
/*checks to see if player is about to hit wall
and then inches them forward as close as it can
until they do*/
if(place_meeting(x + hsp, y, obj_ground))
{
    while(!place_meeting(x + sign(hsp), y, obj_ground))
    {
        x += sign(hsp);   
    }
    hsp = 0;
}
x += hsp;

}
 

Slyddar

Member
I don't see an issue with your horizontal code, or the movement code, except to say flipping the image_xscale can cause wall issues if the masks and origins are not set to allow perfect mirroring.

Also as a side note, your gradual deceleration can be shortened to this :
GML:
if hsp != 0 {
  hsp += -sign(hsp) * dec_const;
  if abs(hsp) < 0.4 {
    hsp = 0;
    my_state = PlayerState.idle;  
  }
}
 
I guess the only thing I would say is you are calling your movement code and THEN calling your collision code, make your collision and movement code in the same script
 

Slyddar

Member
I guess the only thing I would say is you are calling your movement code and THEN calling your collision code, make your collision and movement code in the same script
It's actually his running state. Personally I'd place all the calculating of movement into one script, in case you need to call it in another script. Call it at the top of the running script, then call the collision code, which would have both the horizontal and vertical collisions.
Also Op where are you getting your input? I add it as a script at the top of the states that require it, so you can remove it from some states if needed.
 
It's actually his running state. Personally I'd place all the calculating of movement into one script, in case you need to call it in another script. Call it at the top of the running script, then call the collision code, which would have both the horizontal and vertical collisions.
Also Op where are you getting your input? I add it as a script at the top of the states that require it, so you can remove it from some states if needed.
This is what I meant to say, thank you for clarifying
 

Storm1208

Member
It's actually his running state. Personally I'd place all the calculating of movement into one script, in case you need to call it in another script. Call it at the top of the running script, then call the collision code, which would have both the horizontal and vertical collisions.
Also Op where are you getting your input? I add it as a script at the top of the states that require it, so you can remove it from some states if needed.
So right now the input is being read in within my player object's step event, but your suggestion is a good one! It'd be smart to read in input in a script so that I can decided which states do or don't have access to it.

I went ahead and took your other suggestion as well and converted all the movement code to its own script (so my running state is now just a call to my movement script followed by a call to my horizontal collision script). Unfortunately that didn't seem to fix my collision issues; however, I did notice something interesting.

If the player collides with a wall while the directional input is held, they phase through the wall like I was saying before; BUT, if I run at a wall and then let go close to it (since the player decelerates instead of stopping immediately they'll slide a little bit and eventually touch the wall) they'll collide with the wall properly. I guess when the input is held it doesn't work properly but I'm still unsure why. I'm looking through my code right now trying to find where the issue might be.

EDIT: Wait, I think I found it! I commented out the "image_xscale" line of code and the collision is working properly again. What you were saying about the masks and origins was correct! Do you know how I would go about flipping my character's direction properly? Right now I have their origin set to "bottom center" and am using a placeholder 32x32 square that I'm going to replace with a sprite later.
 

Slyddar

Member
Do you know how I would go about flipping my character's direction properly?
Taken from an answer I just gave of the process.
GML:
if sign(hsp) != 0 facing = sign(hsp);
Add a facing variable in the create event which is -1 or 1 for facing left or right. Get facing from the line above after you've calculated hsp that step. Add a draw event and draw_sprite_ext with facing where image_xscale argument goes.
 
Top