Help with spike collision

Bulldrome

Member
So I've been messing around with the idea of a 2D platformer that uses a shield as its main tool.
One Idea I had is that if the player points their shield toward some spikes as they fall onto them, they'll bounce upward instead of take damage. I've made some basic spikes that will restart the game if the player object touches them but if the shield object touches them, it'll cause the player to bounce up.
My problem is that the player can go 1-3 bounces safely before colliding with the spikes somehow through the shield.
What would you suggest I do to prevent this? Is there some sort of thing with the collision I'm missing?

Right now in my shield object in the colliding with my spike object event I have:

with (obj_player)
{
vsp = -vsp - 2 ; //keeps gaining vertical height if you keep bouncing
}
 
S

spoonsinbunnies

Guest
your problem is probably the fact that the player hits the spikes before the shield actually moves to the player, while it seems like everything happens simultaneiously to our eyes everything moves one at a time in game maker, instead of actually using the shield collision to bounce up use the player collision and check however you put the shield under you in the first place which im assuming is a button so something like
in collision with player
Code:
if keyboard_check(ord("A"))//change this to however you move your shield under you
other.vsp=other.-vsp-2
else
{
//however the player dies goes here
}
[/code/]
 

Bulldrome

Member
I just tried this and it did not work.
I use the directional buttons to dictate what direction the shield is pointing in. I tried having the player object check if the down directional key was pressed otherwise the game would restart. Every attempt just had the game restart and the shield did nothing
 

tagwolf

Member
I just tried this and it did not work.
I use the directional buttons to dictate what direction the shield is pointing in. I tried having the player object check if the down directional key was pressed otherwise the game would restart. Every attempt just had the game restart and the shield did nothing
Sounds like the game isn't registering the shield collision. Put show_debug_message("collision with shield! or whatever!") in specific events and if statements in your step event to narrow down what isn't registering. Without seeing more of your project and what code is in what events it's hard for me to tell what is or isn't happening. Either that or the vspd change isn't enough to stop the player from hitting the spikes or isn't happening in time.

Show debug message is awesome for this because you can output things like:

player speed = 10
shield collision
player speed = 8
player collision
 

Bentley

Member
You're saying the shield-bounce-off-spikes works 3 times, and then doesn't work? You'd have to post the code about shield/spike/player collision
 
Instead of just manipulating the variable 'vsp' in obj_player, have you tried doing it's y position as well? So that the shield collision is actually physically moving the player back away from the spike, rather than having the effect possibly not taking effect until the next step for the player.

Or do the checking for shield impact in the player, using a with statement for the shield object, and then control the players descent through that instead. Something like:
in obj_player:
Code:
if dropping
{
if shield_active // I'm assuming you have an on / off state for whether they use the shield....??
{
with (obj_shield)
{
if !place_meeting(x, y + other.vsp, obj_spike)
{
other.vsp = 2; //whatever is fall speed
}
else
{
other.vsp = - 10 //bounce speed
// maybe also manipulate players y position here as well?
}
}
}

}
x += hsp // ??
y += vsp;
Not sure if that will work (or be any different to what you're already doing), as I'm just going off the top of my head. Would need to test it in an actual project.

EDIT: Here is code I used in a project to test this. Some of the movement code remains from someone else's project that I was helping with, and I've just left it in to see if this basic setup would work.
Code:
key_LEFT    = keyboard_check(vk_left);
key_RIGHT    = keyboard_check(vk_right);

key_W        = keyboard_check(ord("W"));
key_A        = keyboard_check(ord("A"));
key_D        = keyboard_check(ord("D"));

key_SPACE    = keyboard_check(vk_space);

if key_SPACE 
// because I'm not aware of how you're using the shield I'm just turning on it having a sprite index for the collision here
{shield_active = true;
obj_shield.sprite_index = spr_shield;}
else
{shield_active = false;
obj_shield.sprite_index = noone;}


left        = sign(key_LEFT+key_A);
right        = sign(key_RIGHT+key_D);
jump        = sign(key_SPACE+key_W);

var move = right-left;

hSpeed = move * pSpeed; // pSpeed = 5
vSpeed += pGravity; // pGravity = 0.5;
onGround = place_meeting(x, y+1, obstacle_parent);

// COLLISIONS
if(jump && onGround){
    vSpeed = pJump; // pJump = -10;
}

if(jump && onGround){
vSpeed = pJump; // pJump = -10;
}

if(place_meeting(x, y+vSpeed, obstacle_parentl))
{
 while(!place_meeting(x, y+sign(vSpeed), obstacle_parent))
{
 y += sign(vSpeed);
 }
vSpeed = 0;
}

if vSpeed != 0 && vSpeed != pJump // I'm assuming this satisfies the condition that it is airborne
{
if shield_active // shield has sprite active for testing collision
{obj_shield.x = x; // my basic control of the shield here
obj_shield.y = bbox_bottom + vSpeed + sprite_get_yoffset(spr_shield); // my basic control of the shield here
with (obj_shield)
{
if place_meeting(x, y + other.vSpeed, obj_spike)
{
other.vSpeed = other.pJump
}
}
}

}
x += hSpeed
y += vSpeed;
Basically when the shield gets that it's in collision with the spikes it has the same effect as if the player had pressed jump. In this example as long as the space key is pressed it will keep bouncing off the spike, and the player object doesn't die.

Will have to see if it fits with how your project is set up.
 
Last edited:

Bulldrome

Member
I did some more experimenting and used @tagwolf and @spoonsinbunnies advice and got it to work pretty well. Still want to lab with it a bit and fine tune it but the general idea works and I'm happy with that for now.

@Bentley when I had the collision set on the shield object it would work a handful of times with the player bouncing a handful of times before colliding with the spikes through the shield object. Sometimes the player would bounce once, 3 times, 5 times. It was inconsistent. Having the collision linked to the player object positioning the shield works much better

@the_dude_abides I'll definitely try that first code you posted to give the bounce a set height. For now I just wanted the general idea to work so I can tweak it and experiment with it.
Thank you all, you're the real MVPs
 
Code:
with (obj_shield)
{
if place_meeting(x, y + other.vSpeed, obj_spike)
{
other.vSpeed = other.pJump
}
}
This piece of code is the only thing from my suggestion that was added to an already done project to achieve your aim.

I think the reason the second total example works (at least within the basic setup that I have) is due to the first part seeing if there is any collision with the ground. So you have the effect of gravity being figured initially.

Then you have the final part, before any values are applied to the y position, where it tests if there is the shield collision. Which is only that piece of code above.

By ordering it last, the shield overrides anything else and moves the player. Because it's within the player, and being applied to the player, it works infinitely. The only thing I'm not sure about is the shields movement, as it sticks to the player on the way down but is briefly not correct when bouncing up. It lags behind for a little before snapping back into place, which doesn't look great.

But without knowing how you have the shield working I couldn't say how that ought to be fixed, and my implementation here was pretty basic to begin with.
 
Top