GML Reactive object help. This noob found a solution, but I know it's the wrong way.

Game Maker version 2.3.0.529
As you'll probably guess I'm following Shaun Spalding's tutorial but along the way I added a crouch action and multiple oPlayer"weapon" objects using a collision instance_change to allow weapons changes that also change the sprites and how it shoots.
I have a car that is reactive when my Player jumps on it (See attached video)

The issue I had: The car was either reactive and not solid, or it was solid and not reactive. And it was reactive by walking into it too when I only want it to react when jumped on, but I couldn't find a tutorial on vertical-only collision.

What I did: I made a duplicate of the car sprite, cleaned up the shape for better walking on, placed it over the car and lowered the sprite so the reactive car is sticking up. Made the reactive car reactive and the other car non-visible and a child of the oWall object.

I spent a few nights working on this car and I managed to stick together something that works, but I know it's the wrong way to go about it. I'm sure many of you vets on here would be like "Oh, that's all? Here's an easier, cleaner way. Click click boom, here ya go."

Thanks.

Code:
##Character Create###
hsp = 0;
vsp = 0;
grv = 0.3;
walksp = 4;

firingdelay = 0;

controller = 0;

###Character Step###
//Get player input
key_left = keyboard_check(ord("A")) || gamepad_button_check(0,gp_padl);
key_right = keyboard_check(ord("D")) || gamepad_button_check(0,gp_padr);
key_down = keyboard_check(ord("S")) || gamepad_button_check(0,gp_padd);
key_jump = keyboard_check_pressed(vk_space);
Action = keyboard_check_pressed(vk_enter);

if (key_left) || (key_right) || (key_jump)
{
    controller = 0;    
}

if (abs(gamepad_axis_value(0,gp_axislh)) > 0.2)
{
    key_left = abs(min(gamepad_axis_value(0,gp_axislh),0));
    key_right = max(gamepad_axis_value(0,gp_axislh),0);
    key_up = abs(min(gamepad_axis_value(0,gp_axislv),0));
    key_down = max(gamepad_axis_value(0,gp_axislv),0);
    controller = 1;
}

if gamepad_button_check_pressed(0,gp_face1)
{
    key_jump = 1;
    controller = 1;    
}

if gamepad_button_check_pressed(0,gp_face3)
{
    Action = 1;
    controller = 1;    
}

//Calculate movement

var move = key_right - key_left; //Tells if both keys are pressed or released, no action is taken.

hsp = move * walksp;

//These turn the sprite right,left while crouching
if (place_meeting(x,y+1,oWall)) && (key_down) && (key_right)
{
    hsp = 0;
    image_xscale = 1;
}

if (place_meeting(x,y+1,oWall)) && (key_down) && (key_left)
{
    hsp = 0;
    image_xscale = -1;
}

vsp = vsp + grv;

//Jump collision
if (place_meeting(x,y+1,oWall)) && (key_jump) //This only allows jumping when touching the ground.
{
    vsp = -7;
}


//Horizontal collision
if (place_meeting(x+hsp,y,oWall))
{
    while (!place_meeting(x+sign(hsp),y,oWall)) //Ensures complete contact with object
    {
        x = x + sign(hsp);
    }
    hsp = 0;
}

x = x + hsp;

//Virticle 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;

//Animation
//If player is jumping or falling
if (!place_meeting(x,y+1,oWall))
{
    sprite_index = sPlayerARJumpFall;
    image_speed = 0;
    if (sign(vsp) > 0) image_index = 1; else image_index = 0; //This choses between which frame will be used, up or down.
    
}
else
{
    image_speed = 1;
    if (hsp == 0)
    {
        sprite_index = sPlayerAR;
    }
    else 
    {
        sprite_index = sPlayerARR;
    }
}


//Crouch
if (place_meeting(x,y+1,oWall)) && (key_down)
{
    sprite_index = sPlayerAR_crouch;
}


//Image flips to changing direction
if (hsp != 0) image_xscale = sign(hsp);

###Car create###
image_speed = 0;
image_index = 0;

###Car Step###
//If in contact with any of these object, car reacts
if (place_meeting(x,y,oPlayerFist)) || (place_meeting(x,y,oPlayerAR)) || (place_meeting(x,y,oPlayerMolotov))
{
    image_index = 1;
}
else
{
    image_index = 0;    
}
 

TheouAegis

Member
If you make it solid, the game will shove the player outside of the collision and then run the collision event. At that point you could check if bbox_bottom < other.bbox_top (assuming this is in the player object's Collision With Car event).

If you don't make it solid, you can check if yprevious is less than the car's bbox_top.

Or if you want the player to jump into the door, just check if vspd is greater than 0 when you collide with the car.

You don't need a duplicate car sprite to change collisions. Just make a sprite the size of the collision mask you want, then set the cop car's mask_index to that sprite. When the player "enters" the car, set the mask_index to -1. When the player "exits" the car, set the mask_index back to that sprite.

If you want the player to be able to jump onto the car and use it as a platform, but also enter it, you could fast-toggle the mask_index (that is, set the mask index, check for one type of collision, then change the mask so you can check for another collision). Or just use simple math to calculate if the player is colliding with the car in one way or another.
 
Or if you want the player to jump into the door, just check if vspd is greater than 0 when you collide with the car.
I have no plans for the character to enter the car, just walk and jump on it. (Later I am going to re-make the car so it's all burned and smashed up)

I tried turning oPolice_car1 solid "on" and I muted all the code in its step event.
In my player object I created a collision event set to the car and put in:
Code:
[/INDENT][/INDENT]
[INDENT][INDENT]if (bbox_bottom < other.bbox_top)[/INDENT][/INDENT]
[INDENT][INDENT]{[/INDENT][/INDENT]
[INDENT][INDENT]    other.image_index = 1;[/INDENT][/INDENT]
[INDENT][INDENT]}[/INDENT][/INDENT]
[INDENT][INDENT]else[/INDENT][/INDENT]
[INDENT][INDENT]{[/INDENT][/INDENT]
[INDENT][INDENT]    other.image_index = 0;[/INDENT][/INDENT]
[INDENT][INDENT]}[/INDENT][/INDENT]
[INDENT][INDENT]

^ I tried fixing that indent code three times and even removed it entirely only for it to come back. Done.​
I was able to land on the car but it didn't react and I got stuck on it unable to move.​
I'll admit, I don't even get what the "Solid" selection does when we have to write code telling things how to land on them. (Shrug)​
I tried using the "Other.image_index" in hopes that it would be more specific as I realized if I entered a specified object then all the cars in the room would react.​
 
Last edited:

TheouAegis

Member
solid sets everything back to their previous coordinates when a collision is detected. If you move 1 pixel at a time, or use place_free(), then solid works fine enough.
 
Top