Why does my enemy keep shooting even though I've killed him?

Hi, here is the game: https://arcade.makecode.com/S26830-65682-09574-13150
I’ve tried several things to stop the enemy from shooting bullets after death, but they haven’t worked. Maybe someone has a solution.
I use two extensions:

6 Likes

nothing is wrong on my computer and great game

2 Likes

Cool game. I also have the same issue

1 Like

Sorry, I forgot to clarify that even if the sprite dies, it is still considered alive when using the Sprite.Utils code (compare sprite distance), which causes it to continue creating bullets sometimes or not other times.

2 Likes

This is happening because the variable that “holds” the sprite is still holding all that sprite data (not technically what’s happening but whatever) so the “distance to” function can still find the x and y of the sprite. The sprite is still technically destroyed though, because it has been removed from the rendering code, and it is also removed from the “array of all sprites of kind…” function.
What you want to do (and what you’ll need to do later if you want multiple of the same kind of enemy in a single level) is use something like
“for (let sprite of sprites.allOfKind(SpriteKind.Enemy))” to run code on every enemy of that type. This way, sprites that have been “destroyed” will not run code and won’t spawn random projectiles!

2 Likes

Hi, I think I understand, but if it’s not too much trouble, could you please show me an example or something similar? Thanks a lot

2 Likes

Another question, if I wanted to create a variable to know when an enemy dies, how could I do it?

1 Like

Oops I forgot about this topic! I think I was gonna respond when I got home or something and forgot.

game.onUpdateInterval(2000, function() {
        for (let revolver of sprites.allOfKind(SpriteKind.Enemy2)) {

            DistanceEnemies2 = spriteutils.distanceBetween(player, revolver)   
            console.log(DistanceEnemies2)

            if (DistanceEnemies2 < 75 &&  4 < DistanceEnemies2) {
                revolver.setImage(assets.image`revolvershoot`)
                animation.runImageAnimation(revolver, assets.animation`revolvershoot`, 800, false)
                enemyprojectile = sprites.createProjectileFromSprite((assets.image`enemyprojectile`), revolver, Render.getAttribute(Render.attribute.dirX) * -25, Render.getAttribute(Render.attribute.dirY) * -25);
                enemyprojectile.setKind(SpriteKind.EnemyProjectile)
                sprites.onOverlap(SpriteKind.Enemy2, SpriteKind.Player, function (sprite, otherSprite) {
                    info.changeLifeBy(-1)
                    sprites.destroy(sprite, effects.fire, 1000)
               
                })
                sprites.onOverlap(SpriteKind.Projectile, SpriteKind.Enemy2, function (sprite, otherSprite) {
                    sprites.destroy(otherSprite, effects.blizzard, 500)
                    info.changeScoreBy(25)
                    DistanceEnemies2 = 0
                })

                sprites.onOverlap(SpriteKind.EnemyProjectile, SpriteKind.Player, function (sprite, otherSprite)  {   
                    info.changeLifeBy(-1)
                    sprites.destroy(sprite, effects.fire, 1000)
                })

            }
        }
    })

umm so yeah basically that AllOfKind thing is an array of all sprites of that kind, and when they die they get removed from that list, so I put a loop around your code that loops through that list of Enemy2 sprites and runs the code on them. The reason I made it “For (let revolver…)” is so that I didn’t have to change the variable inside the code and instead I just replaced it. Anyways I really enjoyed this one because not enough people code in JavaScript like me!

1 Like

There are two possibilities here… or 3 depending on how deep in the code you are willing to dive…

If you are trying to run a bit of code when a certain type of enemy dies, there is a sprite event for that:


sprites.onDestroyed(SpriteKind.Enemy, function (sprite: Sprite) {

})

That function will run whenever a sprite of kind “Enemy” dies, but you can change the sprite type of course. That “sprite” variable holds the sprite that just died.

There is also an event for individual sprites, and I think that would just be like


mySprite.onDestroyed(function (sprite: Sprite) {

})

And you would set it up right after you create the sprite in the code.

Now the third option is a bit more complicated, but I think this is actually the one you are looking for. To check if a certain sprite has the flag “destroyed” set to true, we can use this if statement here:


if (mySprite.flags & 2) {

}

“mySprite” being whichever sprite you want to check, of course. I just use it as an example because it’s the default sprite variable in block code.

A very long explanation of how that works...

Sprites all have this variable attached to them called “flags”. It’s a single variable, and every bit (1 or 0) is a different true/false “flag” that tells the physics and rendering engine different stuff about that sprite.

If anyone was wondering, this is where all those flags like “invisible”, “bounce on wall”, “ghost” and “relative to camera” are stored, all in a single variable!

So anyways, there is a flag for “destroyed” in there somewhere, and the real trick is figuring out how to check if a certain bit is “flipped” (1, aka true). We do this using the “&” bit operator.

The & operator outputs a number much like how the “+” operator does, but instead of adding two numbers together it “ands” them, outputting a number where each bit is flipped to 1 only if that bit is 1 in both numbers!

For example: 00110011 & 00101000 = 00100000 because only the 6th bit is flipped in both numbers! (At least I think that’s what you would say, because bit order is right to left, so it’s called the 6th bit and not the 3rd… I think…)

So to check if a certain bit is flipped we can “&” the “flags” variable with another number that only has the “destroyed” bit flipped. After a bit of digging into code, it turns out that the “destroyed” flag is the 2nd bit in the flags variable, corresponding to a value of 2!

(You can find out other flag values by writing “sprites.Flag.“ and then scrolling through the list that pops up of suggested flags. Then you can click on one to auto-fill it and hover your cursor over the variable to see what number it is. Because of the way binary works, each number is a power of 2, representing a single bit flipped!)

So yeah, you “and” the flag value with 2 and if the number that comes out is not 0, that means the “destroyed” flag is flipped, and the sprite is destroyed!

Oh, and we don’t have to use “ != 0 “ or anything because any number in an If statement that isn’t 0 counts as “true”.

P.S. All the issues I solve for people here are always using blocks, so it’s really refreshing to use JavaScript for once! You can do so much more in Makecode when you aren’t using blocks!

2 Likes

thanks you very much! I feel that although programming with blocks is good for learning, programming with code languages ​​is more entertaining sometimes, have a nice day

1 Like

I don’t wanna be a bother and compliment the game without helping but this game genuinely has a really awesome art style. I don’t see stuff like this often, keep working on it!

1 Like