I'm currently making a 2D platformer game within Gamemaker 2 and I'm using GML as the language.
I've had the idea of making a mechanic in my game where the player is able to aim a gun around themselves in a 360 degree radius. I want it to be so that I can click to shoot the gun and I'm propelled in the opposite direction in which I shot towards. I'm not sure how to actually go about this as I've done quite a bit of research and am unable to come up with a solution within my code.
First I found a formula to be able to calculate the opposite direction in which I was first aiming in so that I would be able to figure out what direction I need to propel the player when shooting but now I'm having trouble with moving the player in said direction. I've tried:
{ y += (sign(vSpd)*-100); }
just to test it out to see if it works which it does but I'm not sure what direction to go to get the player to move smoothly instead of teleporting/Jumping to the point calculated. Please help any info or help is greatly appreciated!!!
Note my objects are oPlayer and oBlock and my Sprites are sPlayer, sBlock, and sAimHelp Here is my code that I am using currently:
Functions Script:
function draw_aim_help()
{
//Drawing Sprite
//Spacing of the sprite
var _XOffset = lengthdir_x( weaponOffsetDist, aimDir );
var _YOffset = lengthdir_y( weaponOffsetDist, aimDir );
//Flipping the sprite
var _weaponYscl = 1; // direction of sprite < or >
// edit out if needed
/*if aimDir > 90 and aimDir < 270
{
_weaponYscl = -1;
}
*/
draw_sprite_ext( sAimHelp, 0, x + _XOffset, centerY + _YOffset, 1, _weaponYscl, aimDir, c_white, 1)
depth = -bbox_bottom;
};
function get_aim_direction()
{
if aimDir >= 90 and aimDir < 270
{
dirCheck = -1;
}
else dirCheck = 1;
}
Create Event:
hSpd = 0;
vSpd = 0;
pGrv = 0.3;
plrSpd = 4;
grounded = 0;
vSpd_max = 15;
jump = -10;
jumpMod = 1.5;
//variables for aim
#region
weaponOffsetDist = 128;
centerYOffset = 0;
centerY = y + centerYOffset;
aimDir = 0;
dirCheck = 0;
#endregion
Step Event:
//Movement Inputs
#region
leftKey = keyboard_check( ord("A"));
rightKey = keyboard_check( ord("D"));
jumpKey = keyboard_check_pressed(vk_space);
jumpKeyHeld = keyboard_check(vk_space);
//Weapon Inputs
swapKeyPos = keyboard_check_pressed( ord("W"));
swapKeyNeg = keyboard_check_pressed( ord("S"));
shootKey = mouse_check_button_pressed( mb_left );
//get aiming direction
get_aim_direction()
#endregion
//propulsion mechanic
if shootKey
{
weapon_propulsion();
};
//Movement
#region
//Player Movement
var _horizKey = rightKey - leftKey;
hSpd = _horizKey * plrSpd;
vSpd = vSpd + pGrv;
//jumping
if jumpKey = 1 and grounded = true
{
vSpd += jump;
}
if vSpd < 0 and (!jumpKeyHeld)
{
vSpd = max(vSpd, jump / jumpMod)
}
//Gravity
vSpd += pGrv;
//Max speeds
vSpd = clamp(vSpd, -vSpd_max, vSpd_max);
//Horizontal movement
if (place_meeting( x+hSpd, y, oBlock ))
{
while (!place_meeting( x+sign( hSpd ), y, oBlock ))
{
x = x + sign( hSpd );
}
hSpd = 0;
}
//Vertical Movement
if (place_meeting( x, y+vSpd, oBlock))
{
while (!place_meeting( x, y+sign(vSpd), oBlock))
{
y = y + sign(vSpd);
}
vSpd = 0;
grounded = true;
}
else { grounded = false; };
x += hSpd;
y += vSpd;
#endregion
//Aiming
centerY = y + centerYOffset;
aimDir = round(point_direction( x, centerY, mouse_x, mouse_y));
aimDirInv = ( aimDir + 180 ) mod 360;
pushVar = degtorad(aimDirInv);
Draw Event: // Just for debugging process
draw_self();
draw_aim_help();
draw_text( x, y, string(aimDir));
draw_text( x, y+20, string(aimDirInv));
draw_text( x, y+40, string(pushVar));
draw_text( x, y+60, string(dirCheck));
To get your propulsion movement smoother you'll first want to define a few more values in your create event:
Then in your step event you'll update your propulsion:
Lastly you'll apply this by your movement section, also in the step event:
Effectively, you want to apply the maximum initial force to your character then have it decelerate over time. We accomplish this by moving only a limited amount of pixels every single frame then decreasing that amount the longer the 'recoil' goes on to simulate that air resistance. Of course the specific values of how fast you start moving and how much you slow down by over time will change as the numbers provided above are just filler/an example.
Aside from this a recommendation i have would be to consider implementing a finite state machine. It takes a bit of setup and getting used to but it will save you a LOT of headaches in the long run. There was a good article on the gamemaker website that covered the basics for that if you're interested. Hope this helps: https://gamemaker.io/en/tutorials/coffee-break-tutorials-finite-state-machines-gml