Need help being reflected/knockbacked from an object

M

Mikal

Guest
Trying to make a mechanic similar to Ori and the blind forest where the character can hold right click and after a certain amount of time be reflected/knockbacked to the same direction the mouse is facing. I got the timer to work but it shoots my character vertically. Looking for it to shoot both x and y directions towards the mouse. Kind of like a arc or parabola. Any help is appreciated!

What I have for knockback code:

with(oPlayer)
{
direction = point_direction(other.x, other.y, mouse_x, mouse_y);
hsp = lengthdir_x(20, direction);
vsp = lengthdir_y(20, direction);
if(sign(hsp) != 0) image_xscale = sign(hsp);
}
I can show more code if needed
 

Simon Gust

Member
You will have to Show us your movement Code. Most likely, somewhere you have hsp = …… and it is overwriting your knockback instantly. Where as your vsp is never set directly, just affected by gravity. You will have to implement some kind of overspeed handling.
 
M

Mikal

Guest
I also believe it had something to do with overwriting, heres some of the basic movement code:

var move = key_right - key_left;

hsp = move * walksp;

vsp = vsp + grv;

there is also some animation and collision code but i dont see how it would clash with the hsp
 
Code:
hsp = move * walksp;
@Simon Gust was right - this code will be immediately cancelling out the hsp knockback value you set.

You'll need to employ a state machine preferrably, or set a boolean flag when the knockback happens.

Code:
with(oPlayer)
{
    direction = point_direction(other.x, other.y, mouse_x, mouse_y);
    hsp = lengthdir_x(20, direction);
    vsp = lengthdir_y(20, direction);
    if(sign(hsp) != 0) image_xscale = sign(hsp);
    // Flag to track that knockback/reflection is happening 
    knockback = true;
}
Movement code
Code:
var move = key_right - key_left;

// If we're not being knocked back, do normal movement calculation
if ( !knockback )
{
    hsp = move * walksp;
}

// Need some code here to check if knockback/reflection has finished
if ( place_meeting(x, y+1, obj_ground) )
{
    knockback = false;
}

vsp = vsp + grv;
Something like that :)
 

Simon Gust

Member
Lets see.
you let vsp unaffected by adding or subtracting (or multiplying / dividing or any other operation other than setting).
The same you need to do for hsp.

The problem is, that you do not want hsp to go indefinite if you do
Code:
hsp += move * walksp;
You have to define a maximum speed hsp can reach. Then you need to implement deceleration (and maybe acceleration) so that when you are affected by knockback you don't stay at that speed until you stop.
You can do it by adding and subtracting
Code:
//Creating starting values
var acc = 0.15 * walksp; // acceleration
var dec = 0.15 * walksp; // deceleration

if (move != 0) // if you are pressing a direction
{
    // reduce overspeed via deceleration to walksp
    if (abs(hsp) > walksp)
    {
        if (hsp >  walksp) hsp = max(hsp - dec,  walksp);
        else
        if (hsp < -walksp) hsp = min(hsp + dec, -walksp);
    }
    else
    {
        // normal acceleration
        if (move > 0) hsp = min(hsp + acc,  walksp);
        else
        if (move < 0) hsp = max(hsp - acc, -walksp);
    }
}
else // not moving
{
    // reduce overspeed via deceleration to 0
    if (hsp < 0) hsp = min(hsp + dec, 0);
    else
    if (hsp > 0) hsp = max(hsp - dec, 0);
}
 
Top