Ok, so I’m trying to make a block which repeats for a certain amount of seconds. It’s supposed to stop as soon as the seconds reaches its target, but because of repeat until <> semantics, it doesn’t stop exactly at 3 seconds, but it also has to wait for the iteration to finish.
Is there any way to make it stop as soon as the condition is false?
You might need to create a custom block so that stop [this block V]can work. But then you could insert an if in between each step of the process, something like this:
repeat until <3 seconds have passed> {
say [Step 1]
if <3 seconds have passed> {
stop [this block V]
}
say [Step 2]
if <3 seconds have passed> {
stop [this block V]
}
say [Step 3]
if <3 seconds have passed> {
stop [this block V]
}
}
Of course, replace the “say Step 1/2/3” blocks with what is actually going to be happening in those steps. And replace the <3 seconds have passed> predicate with the actual check you’re using.
In theory there’s no need for the final if <3 seconds have passed> {
stop [this block V]
} block after step 3 because the repeat block will do that check. But if you want to add a step 4, then you’d have to remember to add an “if 3 seconds have passed” in between steps 3 and 4. This way, you just have to right-click the say [Step 3] block and choose Duplicate, and the attached “if 3 seconds have passed” check will also be duplicated with it.
It works by creating a separate sprite to run the loop, which allows me to stop just that script when the condition is true. The reason there’s two sprites, is because for some reason when sprite 1 tells sprite 2 to run a script, stopping scripts in sprite 2 doesn’t stop the script that sprite 1 told sprite 2 to run. However, stopping sprite 1 will stop that script. In this case, I use (loop caller) as sprite 1, and (loop runner) as sprite 2, so I can stop (loop caller) to stop the loop, but not the rest of the scripts in the main sprite.
P.S. The (condition) input is set to unevaluated, so that’s why I have to call it. If it wasn’t unevaluated, then the condition value will never change.
P.P.S. If you don’t know why the script in the loop is still running on the parent sprite instead of the temporary sprite, then you’ll have to learn about scope context, which I’m sure you can read about in the snap manual.
This is the method I came up with. Here’s the thing with the “Turtle sprite” option in that block, instead of creating a clone of the current sprite or any user created sprite, that creates a completely empty sprite.
When a ring is created, it remembers what sprite and script created it. That way no matter where the ring us ran, it will always run in the sprite it was created in, and can also access any variables that were in the script that created it.