Discuss Scratch

JWmeteor
Scratcher
15 posts

Help with my Shooter Game!

Hello, scratchers! I have this bug in my shooter game, Triangle Man Game, which is a collab between me and @krazyQ.
But there is a bug in the game. The level system works, though! The player can reach the top of the screen to move to the next level and they can go back to the bottom to go to the previous level. It works!
Except the enemy spawning system for the levels. I'm going to try to explain it to you. So basically the enemies aren't spawning on the correct level, and everything is just wonky.
Try the game out for yourself to see the issue. Thanks for reading, and please help the development with the game!
Here is the game's link: https://scratch.mit.edu/projects/1366371219

-@JWmeteor
-duckergames-
New Scratcher
20 posts

Help with my Shooter Game!

I see why. In the enemies sprite, you did
when I receive [next level v]
and then there was a custom block “spawn enemies”

and on the define spawn enemies, you had if :level = 2 then create clone of myself 3 times.

i think why it doesnt spawn on level 2 is because when you were running the spawn enemies custom block script, the level variable has still not caught up to 2, so the custom block thinks its 1.

(i think this is the case tell me if im wrong)

cool game btw

Last edited by -duckergames- (Aug. 5, 2026 15:47:04)

JWmeteor
Scratcher
15 posts

Help with my Shooter Game!

-duckergames- wrote:

I see why. In the enemies sprite, you did
when I receive [next level v]
and then there was a custom block “spawn enemies”

and on the define spawn enemies, you had if :level = 2 then create clone of myself 3 times.

i think why it doesnt spawn on level 2 is because when you were running the spawn enemies custom block script, the level variable has still not caught up to 2, so the custom block thinks its 1.

(i think this is the case tell me if im wrong)

cool game btw
thanks but I don’t really understand

Last edited by JWmeteor (Aug. 5, 2026 16:34:08)

mrgibbles10
Scratcher
26 posts

Help with my Shooter Game!

JWmeteor wrote:

thanks but I don’t really understand
The problem is indeed with the level change system.

In the player sprite, the :Level variable is changed AFTER NextLevel or PreviousLevel is broadcast.
This is why the enemies are spawning in the wrong places, because they are running off of old data.

if <(y position) > (175)> then
broadcast (NextLevel v)
end

when I receive [NextLevel v]
change [:Level v] by (1)
set y to (-175)

The :Level variable change needs to be performed BEFORE NextLevel is broadcast.
At this point, you don't really need to recieve NextLevel or PreviousLevel in the Player sprite; just move those events into the “if” condition:

if <(y position) > (175)> then
change [:Level v] by (1)
set y to (-175)
broadcast (NextLevel v)
end
if <(y position) < (-175)> then
change [:Level v] by (-1)
set y to (175)
broadcast (PreviousLevel v)
end

In addition, here are some other things that I noticed, though not really problems with the code:
  • It doesn't look like there are any more spawns setup for the enemies in the Enemy sprite (SpawnEnemies only has a condition for level two), so enemies will only spawn when ADVANCING into the second level, not returning. The SpawnEnemies block is only called on the NextLevel event, not PreviousLevel event. I would guess that this is intentional.

  • It might also be a good idea to keep track of cleared levels, as returning to level two by first going back to level one will respawn the enemies.

Edit: I also noticed that you can RETURN to level one while fighting the enemies in level two, and they will stay on-screen. Returning BACK to level two will also double the enemies on the screen. You might want to look into this.

I hope this helped!

Last edited by mrgibbles10 (Aug. 5, 2026 21:35:17)

JWmeteor
Scratcher
15 posts

Help with my Shooter Game!

mrgibbles10 wrote:

JWmeteor wrote:

thanks but I don’t really understand
The problem is indeed with the level change system.

In the player sprite, the :Level variable is changed AFTER NextLevel or PreviousLevel is broadcast.
This is why the enemies are spawning in the wrong places, because they are running off of old data.

if <(y position) > (175)> then
broadcast (NextLevel v)
end

when I receive [NextLevel v]
change [:Level v] by (1)
set y to (-175)

The :Level variable change needs to be performed BEFORE NextLevel is broadcast.
At this point, you don't really need to recieve NextLevel or PreviousLevel in the Player sprite; just move those events into the “if” condition:

if <(y position) > (175)> then
change [:Level v] by (1)
set y to (-175)
broadcast (NextLevel v)
end
if <(y position) < (-175)> then
change [:Level v] by (-1)
set y to (175)
broadcast (PreviousLevel v)
end

In addition, here are some other things that I noticed, though not really problems with the code:
  • It doesn't look like there are any more spawns setup for the enemies in the Enemy sprite (SpawnEnemies only has a condition for level two), so enemies will only spawn when ADVANCING into the second level, not returning. The SpawnEnemies block is only called on the NextLevel event, not PreviousLevel event. I would guess that this is intentional.

  • It might also be a good idea to keep track of cleared levels, as returning to level two by first going back to level one will respawn the enemies.

Edit: I also noticed that you can RETURN to level one while fighting the enemies in level two, and they will stay on-screen. Returning BACK to level two will also double the enemies on the screen. You might want to look into this.

I hope this helped!
The enemies on different screens could be fixed by a list or just hiding the clones instead of deleting them for the list option. I was planning to look in onto it. Thanks for your advice! I will try it later since I don’t have much time right now, but thanks! Appreciate you helping!
JWmeteor
Scratcher
15 posts

Help with my Shooter Game!

-duckergames- wrote:

I see why. In the enemies sprite, you did
when I receive [next level v]
and then there was a custom block “spawn enemies”

and on the define spawn enemies, you had if :level = 2 then create clone of myself 3 times.

i think why it doesnt spawn on level 2 is because when you were running the spawn enemies custom block script, the level variable has still not caught up to 2, so the custom block thinks its 1.

(i think this is the case tell me if im wrong)

cool game btw
Hey I understand it now, thanks man! I will check out your game now!
JWmeteor
Scratcher
15 posts

Help with my Shooter Game!

mrgibbles10 wrote:

JWmeteor wrote:

thanks but I don’t really understand
The problem is indeed with the level change system.

In the player sprite, the :Level variable is changed AFTER NextLevel or PreviousLevel is broadcast.
This is why the enemies are spawning in the wrong places, because they are running off of old data.

if <(y position) > (175)> then
broadcast (NextLevel v)
end

when I receive [NextLevel v]
change [:Level v] by (1)
set y to (-175)

The :Level variable change needs to be performed BEFORE NextLevel is broadcast.
At this point, you don't really need to recieve NextLevel or PreviousLevel in the Player sprite; just move those events into the “if” condition:

if <(y position) > (175)> then
change [:Level v] by (1)
set y to (-175)
broadcast (NextLevel v)
end
if <(y position) < (-175)> then
change [:Level v] by (-1)
set y to (175)
broadcast (PreviousLevel v)
end

In addition, here are some other things that I noticed, though not really problems with the code:
  • It doesn't look like there are any more spawns setup for the enemies in the Enemy sprite (SpawnEnemies only has a condition for level two), so enemies will only spawn when ADVANCING into the second level, not returning. The SpawnEnemies block is only called on the NextLevel event, not PreviousLevel event. I would guess that this is intentional.

  • It might also be a good idea to keep track of cleared levels, as returning to level two by first going back to level one will respawn the enemies.

Edit: I also noticed that you can RETURN to level one while fighting the enemies in level two, and they will stay on-screen. Returning BACK to level two will also double the enemies on the screen. You might want to look into this.

I hope this helped!
Thanks again, and I fixed the enemies spawning, but when you kill an enemy in one level, go back one level, then go forwards one level, that enemy you killed is there again! What is a fix for this? Maybe lists, but it might get too complicated. Or maybe just showing and hiding might work!
mrgibbles10
Scratcher
26 posts

Help with my Shooter Game!

JWmeteor wrote:

Thanks again, and I fixed the enemies spawning, but when you kill an enemy in one level, go back one level, then go forwards one level, that enemy you killed is there again! What is a fix for this? Maybe lists, but it might get too complicated. Or maybe just showing and hiding might work!

Adding a list system to keep track of which enemies have been killed in which specific level would probably require a rebuild of the current system if you wanted it to work in a maintainable way.

I don't know what direction you want to go with game design, but these are (hopefully) some easier fixes.
First, you'll want to create a new variable and a new list for “all sprites” (I know, a list, but bear with me! It only tracks completed levels):

(:ActiveEnemies) //Name them whatever you want; This is just what I came up with :)
(:CompletedLevels :: list)

Make sure to reset these when the flag is clicked!
I put this in the backdrop, but they can go wherever:

when green flag clicked
hide variable [:Score v]
hide variable [:DisplayWorldRecord v]
hide variable [:Level v]
set [:ActiveEnemies v] to (0) // Here
delete all of [:CompletedLevels v] //And here

Then make some changes to the Enemy sprite:

define SpawnEnemies //Make sure that this gets turned to "run without screen refresh"!
if <[:CompletedLevels v] contains (:Level)> then // Add this condition at the beginning; Wrapping it around the entire stack can get messy!
stop [this script v]
end
if <(:Level) = (2)> then
repeat (3)
change [:ActiveEnemies v] by (1) //Add this here
create clone of [myself v]
end
end

Next, under the “when I start as clone” hat block in the biggest stack (the one that contains the DeathAnimation call):

define DeathAnimation
. . .

when I start as a clone
. . .
change [:ActiveEnemies v] by (-1)
if <(:ActiveEnemies) = (0)> then
add (:Level) to [:CompletedLevels v]
end
DeathAnimation //Important that this goes after
delete this clone


From here, two seperate solutions will diverge.
  1. This solution will not allow the player to leave a level until all of the enemies have been defeated.
    Just make a change to the Player sprite:

    define Movement
    . . .
    if <(:ActiveEnemies) = (0)> then //Add this
    if <(y position) > (175)> then
    change [:Level v] by (1)
    set y to (-175)
    broadcast (NextLevel v)
    end
    if <(y position) < (-175)> then
    change [:Level v] by (-1)
    set y to (175)
    broadcast (PreviousLevel v)
    end
    end

  2. This next solution will make killing all enemies when leaving a level much more reliable and robust. Unfortunately, if only some of the enemies are killed, all of them will respawn when re-entering.
    However, this solution does not restrict player movement.
    First, create a variable for “this sprite only”:

    (:IsClone) //Again, name whatever you like!

    Then, add these to the Enemy sprite:

    define SpawnEnemies
    set [:IsClone v] to (1) //Here
    if <[:CompletedLevels v] contains (:Level)> then
    set [:IsClone v] to (0) //Also here
    stop [this script v]
    end
    if <(:Level) = (2)> then
    repeat (3)
    change [:ActiveEnemies v] by (1)
    create clone of [myself v]
    end
    end
    set [:IsClone v] to (0) //And here

    when green flag clicked
    set [:IsClone v] to (0) //Important! Without this, the game can break (enemies will never spawn)!

    when I receive [NextLevel v] //You can just change the existing "NextLevel" boardcast
    if <(IsClone) = (0)> then
    set [:ActiveEnemies v] to (0)
    SpawnEnemies
    end

Hopefully, you can make use of some of these solutions!
I tried both, and they seem to work properly. If you try them out yourself, tell me if you find any new bugs!

Last edited by mrgibbles10 (Today 07:05:51)

Powered by DjangoBB