GML Collision masks daughters independent of the object mask GameObject

GGJuanPabon

Member
My English is bad but I will try to explain. I need your help.




The problem you see in the video, happens because I have an isGround variable and another isJumping variable that is triggered in false or true if it touches the ground or jumps. But since the ceiling is the same object of the ground ... when jumping many times in a row, the error happens.

In Unity, you can create Empty GameObject, and place them as children of your object, as I show in the image. This allows me to shoot events if that object touches something.

I want to do the same in GameMaker, I want my floor not to be confused with my ceiling.

PROBLEM: What is happening to me is that when I jump and touch the ceiling, the perfect collision code acts, leading my player just before colliding, this translates it as isGround and I am having problems with that.

I would like to have more control, having a GameObject above my head and one below my feet, and thus identify if I am touching the ceiling or I am touching the ground.

What would you do? sorry if I sound somewhat cheeky, but, I'm starting with GMS2, and additionally my English is bad.

If you can give me an example code I thank you very much.
 
Last edited:

TheouAegis

Member
else if place_meeting(x,y+1,obj_ground)
should just be else, the conditional is implied and calling it again is bad code that slows down the game.

Change y+=round(yyvel) to just y+=yyvel. You are moving to a position you didn't check for collisions at.
 

GGJuanPabon

Member
If yyVel < 0, the character is moving up, so don't try to place him on the ground.
Thank you @Nidoking, the problem is When the player approaches the ceiling, the code approaches him for a perfect collision, and yyVel reaches 0. When yyVel is 0 the code interprets it as if it were on the floor. I can't validate if yyVel is negative. Or I mean, I can validate it, but it doesn't help me, because after it reaches 0 it is the problem.

else if place_meeting(x,y+1,obj_ground)
should just be else, the conditional is implied and calling it again is bad code that slows down the game.

Change y+=round(yyvel) to just y+=yyvel. You are moving to a position you didn't check for collisions at.
Thank you @TheouAegis, Round allows me to ensure that the decimals when approaching the floor did not interfere with the perfect collision. However that was because my condition was different, maybe I changed it and I forgot to remove the Round. Now I removed it. However, that is not changing the situation. My problem continues.

I also removed the double validation and left only else. Thank you. I usually go through insecurity ... I'm starting. hehe
 

TheouAegis

Member
Well one thing that bugs me is you encapsulated your collision check. Try it this way:

Code:
if yyVel<10 yyVel+=gravedad;
if place_meeting(x,y+1,obj_Ground) {
    yyVel = 0;
    inGround = true;
}
else
    inGround = false;
if place_meeting(x,y+yyVel,obj_Ground)
{
    while !place_meeting(x,y+sign(yyVel),objGround)
        y += yyVel;
    yyVel = 0;
}

Round allows me to ensure that the decimals when approaching the floor did not interfere with the perfect collision
Pixel rounding is fine, but you need to preserve the fractions. Using y=round(y) loses the fraction of y, essentially locking yyVel to integers (e.g., -2,-1,0,1,2) indirectly. Using round(yyVel) is even worse because as soon as yyVel gets close to 0 when jumping, it is 0, freezing you in place. You would need to add yyVel to y, save y mod 1 to a variable, subtract it from y, do all your collision checks and drawing, then add it back to y.
 
Last edited:

GGJuanPabon

Member
Well one thing that bugs me is you encapsulated your collision check. Try it this way:
ok bro, the code with you advice is:

Code:
if (yyVel<10)
{
    yyVel += gravedad;
}
if (place_meeting(x,y+1,obj_Ground))
{
    yyVel = 0;
    isGround = true;
    isJumping = false;
}else
{
    isGround = false;
    isJumping = true;
}

if (place_meeting(x, y+yyVel, obj_Ground))
{
    while (!place_meeting(x, y+sign(yyVel), obj_Ground))
    {
        y += sign(yyVel);
    }
    yyVel = 0;
}
y += yyVel;
But the problem continues to occur, when I jump many times in a row, it overlaps up.
The problem is that I have this validation when jumping.

Code:
if (vkv_JumpUp)
{
    if (isGround && yyVel == 0 && !isJumping)
    {
        yyVel = yyVel - 5;
        isGround = false;
        isJumping = true;
    }
    y += yyVel;
}
When my player touches the ceiling, the code interprets that it is the floor and, isJumping is false and isGround is true in the ceiling.

Therefore it is validated to jump, and if I jump just when yyVel is = 0 (with isGround=true and isJumping=false).... on the ceiling, I overcome the collision and enter obj_Ground.

I need to keep the isGround and isJumping validations for some state machines that I am creating.
 
Last edited:

TheouAegis

Member
Why are you adding yyVel to y there and in your normal code? You're moving twice.

Code:
if (yyVel<10)
{
   yyVel += gravedad;
}
if (place_meeting(x,y+1,obj_Ground))
{
   yyVel = 0;
   isGround = true;
   isJumping = false;

   if vkv_JumpUp
       yyVel = -5;
}else
{
   isGround = false;
   isJumping = true;
}

if (place_meeting(x, y+yyVel, obj_Ground))
{
   while (!place_meeting(x, y+sign(yyVel), obj_Ground))
   {
       y += sign(yyVel);
   }
   yyVel = 0;
}
y += yyVel;
Try it like that, if you can.


My other suggestion is to check your sprites. Make sure all of his sprites have the same collision mask size and position relative to the origin. If one sprite's mask top is closer to the origin than another's, that can cause him to move into the block.
 
Top