I have a program where "stop all" doesn't work sometimes: Wizards w/ bug.
The "stop all" is in a script on the Stage. When a "game over" message is received,
it sets a variable, changes the background, waits a second, and then "stop all".
If the game ends with a moster hitting the wizard hat, everything works as expected.
If the game ends due to the timer, the background changes and the "'game over' received" blocks on all the sprites are highlighted as if the message was received, but the scripts don't stop. You have to click the stop sign to really stop things.
Stranger yet, if you remove the "wait 1 secs" block from the second Stage script, everything works again.
At first I thought maybe sprites couldn't receive their own messages, but I changed some things around so the "stop all" was in a different sprite than the game-ending timer message and that didn't fix anything.
Can anyone tell me what's up?
Offline
I'm not sure if I can explain exactly why, but you should change the broadcast "Game Over" to broadcast "Game Over" and wait. I think it has to do with the fact that the sprite is receiving its own broadcast.
Offline
That works, but doesn't explain things. Like I said, I tried a version where I pulled all the timer stuff out of the Stage and placed it into the "TIME" sprite (sprite1) which was previously doing nothing. The "game over" gets broadcase from the TIME sprite and received by the Stage which is supposed to stop all. However, that tweak did not change the bogus behavior. And I still don't see why having the "wait 1" before the "stop all" makes a difference. Bug in my program, or bug in Scratch?
Offline
weissjd is correct about the problem. It is caused by "game over" continuously calling itself. If you look at the scripts that are on the stage, the "forever" block runs forever, and as quickly as possible. When timer > gamelength, it broadcast game over. Since this is not the "broadcast and wait" block, Scratch continues running what is inside of the forever loop and what is under the "when I receive game over" block at the same time (this is what causes the problem). Inside of "When I receive game over" it sets the time to 0, switches the background, and waits for 1 second. While it is waiting, the forever loop continues running, it again checks that timer > gamelength, and then broadcast "game over". When it sends the broadcast, Scratch starts at the beginning of the "When I receive game over" block, and does not finish waiting one second (it basically overrides the initial broadcast because there was a new one).
As you found out, by using "broadcast game over and wait" the forever loop does not run again because it waits for the blocks under "When I receive game over" to finish. Also, by not waiting that 1 second, you did not give the forever loop a chance to run again, and so the "When I receive game over" stack reaches the "stop all" block.
I hope this clears the problem up,
Paulmedwal
Offline
Got it, thank you.
I find it a bit ironic that elsewhere there are discussion about what to add or not to add to Scratch to keep it "simple" enough for beginning programmers... yet we are indirectly teaching them about things like race conditions, semaphores (or lack thereof), threaded application debugging, and other stuff I didn't get to until I was a junior in college!
Offline