• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Trying to sync enemy attack with enemy animation.

pixeltroid

Member
I'm trying to sync an enemy's attack projectile with it's attack animation. Basically, when the enemy sprite is playing, I want to create the projectile exactly on the 4th image of the sprite animation.

Here's what I've tried:

This is in the enemy's step event...
Code:
if (alarm[0] < 0) {
sprite_index = spr_attack
if (image_index =  4) 
{
att = instance_create(x,y,obj_enemyfireball3);      
att.speed = 3;
}
alarm[0] = 90
}
This code only plays the animation, but doesn't create the enemy projectile (obj_enemyfireball3).

If I take out "if image_index...", the projectile is created but is out of sync with the animation.

How do I make it so that the projectile is launched exactly after the 4th frame in the animation?

Any help would be appreciated!
 

Mk.2

Member
The value of image_index changes in increments defined by the image_speed, so it's usually not a good idea to check if it's an exact value. Either check that it's greater than or equal to that value, or use floor(image_index).
 

pixeltroid

Member
The value of image_index changes in increments defined by the image_speed, so it's usually not a good idea to check if it's an exact value. Either check that it's greater than or equal to that value, or use floor(image_index).
Like this:
Code:
if (alarm[0] < 0) {
sprite_index = spr_attack

if (floor(image_index) == image_number - 1) { 
att = instance_create(x,y,obj_enemyfireball3)
att.speed = 2;
}   
alarm[0]=90 
}
 

Mk.2

Member
Yep, using "if floor(image_index) ==" will work the way you intended when you used "if image_index == ".
 

pixeltroid

Member
Yep, using "if floor(image_index) ==" will work the way you intended when you used "if image_index == ".
It isn't working.

Here's my code....

Code:
if !alarm[0] > 0 {
sprite_index = spr_attack
image_speed = 0.1; 

if (floor(image_index) == image_number - 1) {
image_speed = 0
att = instance_create(x,y,obj_enemyfireball3)
att.speed = 4;
}
alarm[0]=90
}

It just plays the attack animation but doesn't spawn the projectile. What am I doing wrong??
 
How do you know the projectile isn't spawning but can't be seen due to depth, improper sprites, etc? Have you stepped through it with the debugger to see what's going on?
 

Mk.2

Member
It isn't working.

Here's my code....

Code:
if !alarm[0] > 0 {
sprite_index = spr_attack
image_speed = 0.1;

if (floor(image_index) == image_number - 1) {
image_speed = 0
att = instance_create(x,y,obj_enemyfireball3)
att.speed = 4;
}
alarm[0]=90
}

It just plays the attack animation but doesn't spawn the projectile. What am I doing wrong??
I just tested the code. What's happening is that since you're resetting the alarm at the end, the condition of the alarm being at 0 while the image_index happens to be at 4 needs to be met before image_speed will be set to 0 and bullets will start spawning. With the image_speed at 0.1, it cycles through the animation 9 times before this condition is met. Once that happens, it stays that way and spawns a bullet every 90 frames.

You can test this by changing the 0.1 image_speed to something much slower, like 0.01, so that the alarm will definitely reach 0 while it's on each frame.

If the intended behaviour is to reach the final image, stop the animation and fire a bullet every 90 frames indefinitely, the solution is to move where you reset the alarm:

Code:
if (floor(image_index) == image_number - 1) {
image_speed = 0
att = instance_create(x,y,obj_enemyfireball3)
att.speed = 4;

alarm[0]=90
}
 
Last edited:
In your Step event, I feel like this is a more natural way of structuring your code:
Code:
if (alarm[0] < 0) {
   alarm[0] = 90;
   sprite_index = spr_attack
   image_index = 0;
   image_speed = 0.1; 
}
!alarm[0] > 0 is such a weird way of structuring an alarm check. It's not "wrong" per se, but it just makes it more complicated to read and will make coming back and debugging later on when you've forgotten why you did this much harder, just check if the alarm is less than 0. Alarms naturally count down, so this immediately lets you know "Hey this triggers when the alarm has counted down". Now, in the End Animation event:
Code:
if (sprite_index == spr_attack) {
   image_speed = 0
   att = instance_create(x,y,obj_enemyfireball3)
   att.speed = 4;
}
 

pixeltroid

Member
How do you know the projectile isn't spawning but can't be seen due to depth, improper sprites, etc? Have you stepped through it with the debugger to see what's going on?
I know it is spawning. Because the projectile is set to move towards my direction. It works if I take out the "if image_index...." line.
 

pixeltroid

Member
In your Step event, I feel like this is a more natural way of structuring your code:
Code:
if (alarm[0] < 0) {
   alarm[0] = 90;
   sprite_index = spr_attack
   image_index = 0;
   image_speed = 0.1;
}
!alarm[0] > 0 is such a weird way of structuring an alarm check. It's not "wrong" per se, but it just makes it more complicated to read and will make coming back and debugging later on when you've forgotten why you did this much harder, just check if the alarm is less than 0. Alarms naturally count down, so this immediately lets you know "Hey this triggers when the alarm has counted down". Now, in the End Animation event:
Code:
if (sprite_index == spr_attack) {
   image_speed = 0
   att = instance_create(x,y,obj_enemyfireball3)
   att.speed = 4;
}

Thank you! This worked perfectly. Your formatting is much easier to follow mentally. Yes, !alarm[0]>0 is a weird way of doing alarms. I'll apply it to my other objects.

Thanks to Mk.2 for his inputs as well.
 
Top