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

GML SOLVED: Issue with direction of death knockback

BrandNoob

Member
Hi there,

I'm having a frustrating issue with getting enemy objects to be knocked back in the right direction when they have been attacked by the player (i.e. knocked to the left if the player is to the right and vice versa). They are currently being knocked to the right regardless of the position of the player.

When the attack button is pressed, a hitbox object is being created, which has the following code in the step event to detect for a collision with an enemy, deduct a health point, and store the direction from which the attack came:

Code:
if (place_meeting(x,y,pshootable))
{
    audio_play_sound(snhitenemy,30,false);
    
    with (instance_place(x,y,pshootable))
    {
        
        hitfrom = other.direction;
        hp--;
        flash = 3;
        
    }
}
And this is the code in the enemy object's begin step event which is triggered when it's health points reach 0, and handles the movement for the knockback effect:

Code:
if (hp <= 0)
{
    audio_sound_pitch(sninfecteddie,random_range(0.5,1));
    audio_play_sound(sninfecteddie,3,false);
    with(instance_create_layer(x,y,layer,oinfecteddead))   
    {
        direction = other.hitfrom;
        hsp = lengthdir_x(3,direction);
        vsp = vsp -1;
        if (sign(hsp) != 0) image_xscale = sign(hsp) * other.size;
        image_yscale = other.size;
    }
    instance_destroy();
}
For some reason the enemy is always being knocked to the right. What's frustrating is that I have another object with exactly the same code for a projectile weapon which works fine. What have I missed?!

Thanks for any suggestions
 

BrandNoob

Member
Code:
if (done == 0)
{
    //VERTICAL MOVEMENT

    vsp = vsp + grv;


    //HORIZONTAL COLLISION CHECK

    if (place_meeting(x+hsp,y,owall))
    {
        while (!place_meeting(x+sign(hsp),y,owall))
        {
            x = x + sign(hsp);
        }
        hsp = 0;
    }

    x = x + hsp;


    //VERTICAL COLLISION CHECK

    if (place_meeting(x,y+vsp,owall))
    {
        if (vsp > 0)
        {
            done = 1;
        }
        while (!place_meeting(x,y+sign(vsp),owall))
        {
            y = y + sign(vsp);
        }
        vsp = 0;
    }

    y = y + vsp;
}
Thanks for taking a look!
 
What's frustrating is that I have another object with exactly the same code for a projectile weapon which works fine. What have I missed?!
Check the code for the projectile weapon. Are you setting the "direction" variable belonging to it? What about the hitbox instance. Are you also giving it a direction when the hitbox gets created? By default, the value for direction is 0, which is to the right. So you're "hitfrom" value when touching the hitbox is always going to be 0.
 

TheouAegis

Member
Check the code for the projectile weapon. Are you setting the "direction" variable belonging to it? What about the hitbox instance. Are you also giving it a direction when the hitbox gets created? By default, the value for direction is 0, which is to the right. So you're "hitfrom" value when touching the hitbox is always going to be 0.
Ooh. Yeah, good catch. I forgot to consider that pshootable might be handled incorrectly. We do see a lot of people around here applying direction in their knockback codes because they're copying a suggestion from some source that uses direction even though their project doesn't.
 

BrandNoob

Member
Yep, that did the trick. Thanks!
I had daftly assumed that direction would allow Gamemaker to automatically detect the direction an object was moving. Important to know!
 

TheouAegis

Member
Yep, that did the trick. Thanks!
I had daftly assumed that direction would allow Gamemaker to automatically detect the direction an object was moving. Important to know!
As far as I recall, the only things GM automatically updates are xprevious, yprevious, and speed/hspeed/vspeed when used (that is, speed gets updated when hspeed or vspeed change, and vice versa). Maybe the developers felt calculating the inverses to determine the angle was too taxing of a routine for every step?
 
Top