GMS 2.3+ Coding A Proper Hookshot?

Hello there! I am currently working on a side scrolling platform game with a main focus being hookshot based grappling which the player will use to both traverse and fight/grab enemies using a button press based on the direction the player is facing similar to say 2D Zelda.

Currently, I am able to shoot out the ‘hookshot’ object instance and have the x and y of the origin saved(where it was created). When it hits a wall object, it continues to move, but slows down instead of returning to the player. This is as far as I have gotten. I still need a way to check on the hookshot’s step event when it has reached a certain distance from where it was created, check for collisions it can interact with on each step and if a hookshot object is already out, when a collision is found or the distance of the rope is reached without collision, pull it back. I also need to create two different “pull it back” functions/scripts based on the type of collision (Pulling the player towards an object, or pulling the object towards the player.)

Now here is my code so far:
Player's Step Event:
Code:
//Imput
key_left = keyboard_check(ord("A")) || keyboard_check(vk_left);
key_right = keyboard_check(ord("D")) || keyboard_check(vk_right);
key_jump = keyboard_check_pressed(ord("W")) || keyboard_check(vk_up);
hook = keyboard_check_pressed((vk_space));
//Caluate movement
var move = key_right - key_left;

hsp = move * walksp;
vsp = vsp + grv;

if (place_meeting(x,y+1,owall)) && (key_jump)
{
    vsp = -7;
}

//Horizontal collision
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
if (place_meeting(x,y+vsp,owall))
{
    while (!place_meeting(x,y+sign(vsp),owall))
    {
        y = y + sign(vsp);
    }
    vsp = 0;
}

y = y + vsp;

//Hookshot
if (hook == true){
    var hooky = instance_create_layer(x + lengthdir_x(64, image_angle),y + lengthdir_y(64, image_angle), "Instances_1",ohookshot);
    hooky.direction=0;
    hooky.speed=7;
 
    if(image_xscale == 1){hooky.direction=0;}
    if(image_xscale == -1){hooky.direction=180;}
}
Hookshot's Create Event:
Code:
hsp= 7;
go_back = false;
control = true

//this is where the x and y are saved
x = oplayer.x;
y = oplayer.y;
var i = 0;
with (ohookshot) {
    saved_x_array[i] = x;
    saved_y_array[i] = y;
    i += 1;
}
Hookshot's Step Event:
Code:
if(instance_exists(oplayer)) {
if((lengthdir_x < 100)) {
speed = -25;
}
}
if (collision_rectangle(bbox_left-1,bbox_top,bbox_right+1,bbox_bottom,owall,true,false))
{
    //hsp = -hsp;
    hsp = 0;
    go_back = true;
}


if (go_back)
{
    move_towards_point(x, y, oplayer)
}


if (oplayer.hook)
{
    if (place_meeting(x,y,oplayer))
    {
        oplayer.hook = false;
        instance_destroy();
    }
}

x += hsp;
Thank you for your time!
 
Last edited:
Update: I have managed to get the hookshot to grab and pull things in the world! Hurray! This is the first big hurtle I had. There's still a lot In need assistance with, however.

I'd like the hookshot to constantly be on the same y axis as the player when out, and for player movement to be stopped while grounded and hook is out and hindered while in the air i.e. the character maintains the jump arc but can do any other inputs while the hook is out and not grabbing anything. The Hookshot also doesn't actually return, to the player if it doesn't hit an object it just goes in the other direction until it does and works as normal. Also the hook only goes in one direction, I'd like to make is so that is goes in the direction the player is facing.

Here is my current code:
Player Step Event
Code:
//Hookshot 
if (hook == true and keyboard_check_pressed(vk_space) and instance_exists(ohookshot) = false){
    
    
    hook = false;
    var hooky = instance_create_layer(x,y, "Instances_1",ohookshot);
    hooky.direction= point_direction(x,y,oplayer.x, oplayer.y);
    hooky.speed=7;
    

    SaveID = hooky;

}
else
{
    alarm[0] = -1;
    ready = false;
}

if (hook == false and keyboard_check_released(vk_space) and SaveID != noone and SaveID.getTargetId != noone)
{
    SaveID.pull = true;
    
}
Player Create Event:
Code:
SaveID = noone;
ready = true;
Player Alarm Event
Code:
ready = true;
Hookshot Create Event:
Code:
pull = false;
stuck = false;
getTargetId = noone;

x = oplayer.x;
y = oplayer.y;
var i = 0;
with (ohookshot) {
    saved_x_array[i] = x;
    saved_y_array[i] = y;
    i += 1;
}

line_length = 0;
line_length_max = 200;
Hookshot Step Event:
Code:
if (pull == true) {
getTargetId.speed = 7;
getTargetId.direction = point_direction(x,y, oplayer.x, oplayer.y)

speed = 7;
direction = point_direction(x,y, oplayer.x, oplayer.y);
}

if (stuck == false)
{
    line_length = point_distance(x,y, oplayer.x, oplayer.y);
    if (line_length >= line_length_max) { 
        speed = -10;
        point_direction(x,y, oplayer.x, oplayer.y) }
}


if (oplayer.hook)
{
    if (place_meeting(x,y,oplayer))
    {
        oplayer.hook = false;
        instance_destroy();
    }
}
Hookshot Collision w/ grabbable object:
Code:
if (stuck == false) {
    stuck = true;
    speed = 0;
    
    getTargetId = other.id;
}
Thank you for your time!
 
Top