GMS 2 Attack Code

T2008

Member
I've continually adjusted by attack code but I can't get it right. The problem is that if the player attacks the enemy, he can just keep pressing attack button and the enemy will die without being able to get attacks in. I've done a few tutorials but nothing seems to work. If there are many enemies, it's not noticeable. Any Ideas? Portions of my code are below:

[The Player creates melee object when press x, etc; I didn't include to keep it brief. If needed, I can include. Thanks for any help!]

ENEMY OBJECT
Collision with player melee object:
Code:
if (alarm[1] == -1) {
    //Reduce Animal Hp
    hp -=global.attack_strength;
    //Increase Skill Points
    global.skill_points_melee +=1;
    //Change Hit To True
    hit = true;
    //Reset Alarm
    alarm[1] = 90;
}
Collision With Player
Code:
//Hurt Player
if (alarm[2] == -1) && (hp > 0) && (!global.climb) 
&& (!global.jump) && (!global.been_hit) { 
    //Reduce Hp
    global.hp -= att;
    //Change Global Been Hit To True
    global.been_hit = true;
    //Reset Hurt Alarm 
    alarm [2] = 60;  
}
//Stop Enemy
x = xprevious;
y = yprevious;
Alarm[1]
Code:
hit = false;
Alarm[2]
Code:
global.been_hit = false;
 

Nidoking

Member
This doesn't seem to be a problem with the same thing happening every step, but with some lack of invulnerability for the enemies between attacks, right? So have another alarm with some buffer time between setting the hit state and setting the state where the enemy is vulnerable.

(Also, it's a bit silly to check alarms directly when you have variables that track those states. Why are you not just checking if (!hit)?)
 

Yal

šŸ§ *penguin noises*
GMC Elder
Collision with player melee object:
Why are you using both alarm[1] and hit to check if you can be hurt? (Actually, you only use alarm[1], so what's hit doing?)

My theory is that something else resets alarm[1], so you can damage the enemy infinitely. You could test this by adding show_debug_message(alarm[1]) in the step event of the enemy. Also try adding a bunch of more debug messages with set strings inside all if statements related to the damage logic, like "I can be hurt: take damage" right after the "reduce animal HP" comment.

Also make sure you didn't use the global hit variable in the enemy damage logic, because since it's shared, that means that ANY enemy leaving a hurt state will enable all other enemies to take damage too.
 

RGiskardR

Member
I had a similar issue. I solved it by creating a ds_list to store any enemy instances the player's melee hitbox collided to.

Before doing any damage, check if the enemy instance is already on that ds_list. If not in the list, add it and do damage, else do nothing.

That way even if the player pressed the attack button a lot of times, only once damage will be dealt to the enemy.

Also, destroy the ds_list and the melee hitbox when the attack animation finishes.
 

T2008

Member
Thanks for all the replies. I seem to have fixed the issue by adjusting my player object attack code. Global.attacking was set to false when x was released. Setting it to false in the animation end event seems to have fixed the problem and the enemies have a chance to hit player now.

Yal, I deleted some code to make it short, but hit variable is also used for flash code, etc.

Nidoking, what would the buffer alarm be like? Why not just adjust the duration of the existing alarms? [sorry if question is dumb, I have no coding background.]

RG - I haven't used ds lists much, as I'm not very advanced. I'll keep this suggestion in mind though.
 

Nidoking

Member
Why not just adjust the duration of the existing alarms?
Because you only had one alarm per enemy. alarm[1] was tracking the player's hit state. So if you want to have a different number of steps for hitstun vs. invulnerability (for example), that has to be two alarms. That way, you can clear one variable to let the enemies move and act while the one that controls whether they can be attacked is still counting down. In this case, it looks like your intention wasn't to have any hitstun, so you don't need an alarm for that.
 
Top