Animations causes bug in collision

Zaksley

Member
Hi guys,
Here is the problem : I have an animated character. When he changes his direction, like left to right, it might cause some problems with the walls. Like getting stuck. Or for my ennemis (also animated just by a simple line), It can teleport them very far, until they find a wall... Also, if my character attacks (there is an animation for it) for the first time, he gets stuck and I have to jump to debug him (then I can attack as much as I want and the problem doesn't come again). Moreover, I'm getting some bugs when I jump and I try to double jump when I spam it. I'm pretty sure it might be because when I land on the wall, the variable double_jump doesn't get reset because of the collision mask and the animation things.

As you can see, a lot of bugs but I'm 90% sure it's all because of the animation cycle that doesn't work well. I don't know how to code something like this properly and maybe there are some rules for the differents sprites in animation ??

Here is my code:

Collision/Movement:

Code:
        //MOVEMENT PLAYER

//Calculate Movement 
var move = checkKeyboard_Right - checkKeyboard_Left; 
hsp = move * walkspeed;
vsp += grv; 


//Jump from floor 
if ( (place_meeting(x, y+1, obj_wall)) && (checkKeyboard_Jump) )
{
    vsp = -8;
}

//Double Jump
if  (!place_meeting(x, y+1, obj_wall) && double_jump) && checkKeyboard_Jump
{
    vsp = - 8;
    double_jump = false;
}

//Vertical Collision
if place_meeting(x+hsp, y, obj_wall)
{
    
    while (!place_meeting(x + sign(hsp), y, obj_wall))
    {
        x += sign(hsp)    
    }
    
    hsp = 0;    
}
y += vsp;

//Horizontal Collision 
if place_meeting(x, y + vsp, obj_wall)
{
    
    while (!place_meeting(x, y + sign(vsp), obj_wall))
    {
        y += sign(vsp)    
    }
    
    if !place_meeting(x, y+vsp, obj_ceiling) 
    {
        //Reset Double Jump
        if !double_jump   double_jump = true;
    }

    vsp = 0;    
}
//Movement 
x += hsp;
The simple line to check if my character is going left or right:
Code:
    // ANIMATION PLAYER
    
if hsp != 0 
{ 
    image_xscale = size * sign(hsp);
    
    sprite_index = spr_run;
    image_speed = 1;
}
It is pretty much all but if you need anything else in my code to help me, I could put the rest !
See you soon ! :)
 

Latch

Member
Have you set collision masks to be precise or is it a static box that doesnt change with the animation? Im having an issue myself with my sprite walking inside an object I am checking for using place_meeting and mine is nothing to do with animation but the way that I have set up the collision detection. I believe I am checking too late and once the check completes, its too late and I am inside of the object, rendering movement impossible.

Have you tried stopping the animations and just having a static sprite, and then checking if the issue continues as I think your issue will be the same as mine (which I am currently trying to solve).
 

Roderick

Member
If your collision masks are squares or circles, and your origin is centered, make sure your masks are an ODD number of pixels on any axis they flip on.

For example, if you have an 8x8 sprite with an 8x8 collision mask, with a centered point of origin, the point of origin will not be between the fourth and fifth pixels, it will be on the fourth one, leaving 3 pixels on one side and four on the other. If you collide with something on the short side and then turn around, you'll suddenly be overlapping, causing collision errors. By having an odd width, you can properly center the mask and have an equal number of pixels on each side.

(This is from my experience with 1.4. I don't know if it changed with any of the 2.x updates)
 

Zaksley

Member
Have you set collision masks to be precise or is it a static box that doesnt change with the animation? Im having an issue myself with my sprite walking inside an object I am checking for using place_meeting and mine is nothing to do with animation but the way that I have set up the collision detection. I believe I am checking too late and once the check completes, its too late and I am inside of the object, rendering movement impossible.

Have you tried stopping the animations and just having a static sprite, and then checking if the issue continues as I think your issue will be the same as mine (which I am currently trying to solve).
Alright I'm going to try it !
And yeah, I tried to have a static sprite, I mean, right now my character sprite isn't static but just, left and right are the same and so it fixed few bugs yeah. Like the ones that I still get for my ennemies. But I need my character to run properly xD

[EDIT] : I put back the left/right animation and I'm getting stuck even with the precise collision mask. So, still same prob :'(
 

Zaksley

Member
If your collision masks are squares or circles, and your origin is centered, make sure your masks are an ODD number of pixels on any axis they flip on.

For example, if you have an 8x8 sprite with an 8x8 collision mask, with a centered point of origin, the point of origin will not be between the fourth and fifth pixels, it will be on the fourth one, leaving 3 pixels on one side and four on the other. If you collide with something on the short side and then turn around, you'll suddenly be overlapping, causing collision errors. By having an odd width, you can properly center the mask and have an equal number of pixels on each side.

(This is from my experience with 1.4. I don't know if it changed with any of the 2.x updates)
Yeah, few collision masks are close to square, I might test this too ! I'm telling you as fast as I can if it's working or not !

[EDIT] I tried with precise collision and there is still this problem. Any idea ?
 

SoapSud39

Member
Instead of making the collision masks the same coordinates on every sprite, what you can do is set the collision mask on one sprite (e.g. the idle animation), and this should be the same every frame (so don't do precise per frame). In your object editor, there's a section to choose collision mask -- choose that specific sprite and not "Same as Sprite". Otherwise the collision mask will change every time you change your sprite in the code. (so when setting the idle sprite mask, it would be the same mask that is used when you switch to run animation)

To solve the image_xscale problem, you can actually get away with not using image_xscale. Instead use a variable similarly named, e.g. 'xscale', and then in the draw event use draw_sprite_ext(), which will let you input different variables like x and y scale, rotation, etc. This will work because when you flip image_xscale, the collision mask flips as well, which may cause problems such as yours, but when you use draw_sprite_ext() with 'xscale', the mask is not flipped, and only the image is.
 
Last edited:
Top