Health draining too fast.

Hello everybody, I know this is a dumb one but you guys can think of things in ways I can't...

I have this health "system" (it's not a system, yet) created that does this...
Code:
//create event
var health_player; //bla bla
health_player = 4; //for example

//step event
if place_meeting(x,y,obj_enemy)
{
health_player -= 1;
}
if health_player = 0
{
instance_destroy();
}
I know why the health is draining too fast, because each time there is that collision it drains one per step.
(Which is way faster then what I want...)

I thought of many ways how to limit the collision. Many didn't work...ended with the same result.
Now, a timer would clearly work. No matter if there is collision it waits for the timer to reach certain values too.
But, I don't want to use a timer (only if that's the only way, which is not).
Others ways that would work, I can not see...

Thanks for the help.
 

Simon Gust

Member
Hello everybody, I know this is a dumb one but you guys can think of things in ways I can't...

I have this health "system" (it's not a system, yet) created that does this...
Code:
//create event
var health_player; //bla bla
health_player = 4; //for example

//step event
if place_meeting(x,y,obj_enemy)
{
health_player -= 1;
}
if health_player = 0
{
instance_destroy();
}
I know why the health is draining too fast, because each time there is that collision it drains one per step.
(Which is way faster then what I want...)

I thought of many ways how to limit the collision. Many didn't work...ended with the same result.
Now, a timer would clearly work. No matter if there is collision it waits for the timer to reach certain values too.
But, I don't want to use a timer (only if that's the only way, which is not).
Others ways that would work, I can not see...

Thanks for the help.
Maybe a kind of invincibility state and animation for the player could be handy.
The player changes to this state if he collides, while in that state he is invincible, plays an animation. When he's done animating, he changes to his previous state (or normal state) and can be hit again. This way you can subtract much greater numbers at once.
 
@Adam Lesiak And then how can you count the "damage" that the enemy does to the player?

Let me explain further, I have a knock-back effect, each time the enemy touches the player it plays a sprite and gets knocked back.
That is not really a good idea to do...just to minimize the damage.

I must be 100% in control of it.

@Simon Gust I actually have all what you said done in the game. What you actually said is just another type of a timer.

But I never thought of it using it this way (told you)....>.<
It's a great idea...what you said is combining the invincibility state and animation with the collision, using the state and animation as a state in which the player can get hit again.
What I thought was using two different timers for the state and for the collision. Timers with the same maximum value, so they sync.
I will try your idea.

Hmm...still open to ideas and concepts. Feel free to share them.
 

Kris Hyre

Member
The invulnerability state is a common one to use alongside the knockback mechanic you have in place when getting hit. There are many ways of setting up state machines, but a simple way of preventing getting damaged every step could be something like setting up a variable like
Code:
// obj_player On Create
 is_hurt = false;

// In Collision Event
if ((place_meeting(x,y,obj_enemy)) and (!is_hurt))
{
health_player -= 1;
is_hurt = true;
alarm[0] = room_speed;
// Perhaps change the sprite to a "hurt" sprite
}

// In Alarm[0] Event
is_hurt = false;
// Perhaps change the sprite back to the "normal" sprite
That's off the top of my head, but should give you an idea of how to set it up. This should give them 1 sec of "invulnerability" to the collision event.
 
Last edited:
@Electros That's great material restricting unwanted repetitions.
Glad to get my hands on something like that. Added to "bookmarks".

@Kris Hyre You're way off...sorry.
You're using alarms...I don't use alarms because there are only 10 of them in GM8. I don't know about other GM's.
I specified that I would like to find out a way without using alarms/timers.
Timers are alarms but made by code.
Here is an example of one second alarm if you have the rooms set to 60 steps.
Code:
//Create event
var timer;
timer = 60;

//Step event
if timer = 0
{
timer = 60;
}else{
timer -=1;
}
You use the timer like this, if timer = 0{do what if the alarm would set off}. Or if timer = 60{do what if the alarm would set off} in some cases.
 
Last edited:

Kris Hyre

Member
Yeah, I missed your line in the OP about not wanting to use a timer, sorry about that. As far as using alarms vs. your timer example, there are a few functional differences, but they are rather similar for the most part. I guess the real question then is

...if you do not want to use a timer to prevent the rapid health loss for a period of time due to collisions every step , what kind of behavior are you looking for?
 
Even though the first hit on the player counts as a "-2 health" for some reason which I am yet to discover, but that's ok I just increased the health by 1.
This is what I was looking for...like I said pretty dumb...

Pattern 1: Anti-Recurrence Flags
Anti-recurrence flags can be used to perform an action only when a condition transitions from false to true. In GM development, this is most common in collisions, where the condition is a collision-checking function like place_meeting().

General pattern:
Code:
Create:
flag = true;

Step:
Code:
if (condition) {
  if (flag) {
   /* One-time action */
   flag = false;
  }
} else {
  flag = true;
}
A common variation leaves out the else completely, preventing the action from running again on future false-true transitions.
I totally removed the else part...because that's what worked, another thing yet to discover why.
This is from FrostyCat's tutorial...https://forum.yoyogames.com/index.php?threads/restricting-unwanted-repetition-with-flags.34455/

I thought of something very similar and it didn't work...for some reasons... -.-
Maybe because I was checking if flag = with something...in FrostyCat's example theres just a checking if flag exists. Yea...there are still many things I don't yet fully understand.

Thanks guys for the help, especially @Electros for sharing this great tut. I won't mark this thread as solved, I kinda want to leave it as an open discussion.
 

Kris Hyre

Member
That is pretty much what I posted for you, using (place_meeting(x,y,obj_enemy) as your condition, and is_hurt as your flag. The only question was how to go about resetting the flag so that you can be hit again later (such as using an alarm or timer).

But ok then, glad you found something that works for ya. ¯\_(ツ)_/¯
 
@Kris Hyre Your approach was great, no doubt, but I am trying to stay away from alarms as much as possible.
Since you're using alarms I thought (don't know why) that you don't know what a timer is... >.<
 

Simon Gust

Member
@Kris Hyre Your approach was great, no doubt, but I am trying to stay away from alarms as much as possible.
Since you're using alarms I thought (don't know why) that you don't know what a timer is... >.<
Another reason to stay away from alarms is that you can't pause them. If you want a pause system in your game you have no simple way of pausing alarms. Happened to me, changed all alarms to manual timers.
 
Top