ScratchData LogoScratchData
Back to _nix's profile

Instant Broadcasts w/ Easy Rendering

_N_nix•Created November 7, 2021
Instant Broadcasts w/ Easy Rendering
15
9
166 views
View on Scratch

Description

More investigations into how timings work in Scratch! Basically, one "tick" of Scratch involves taking all the scripts which are currently running and running each of them until a "yield". (The most common yield points are at every time a loop loops.) If any motion or looks blocks were used, Scratch requests a "screen refresh", which means it will intentionally delay for one frame (1/30th of a second) to show the results of the motion/looks/etc on-screen. The key thing I just learned (or made sense of :P) is that these blocks don't request a screen refresh IF the sprite/clone is hidden. Also, the "hide" block amazingly *doesn't* request a screen refresh—check out the JavaScript code for setVisible(false) here: https://github.com/LLK/scratch-vm/blob/be6deda9fadcfbbe5327f763c869f6b2c17cfcf3/src/sprites/rendered-target.js#L354-L357 This means we can hide at the start of a script which has motion/looks blocks, and it won't count as a screen refresh. Then, we can do as many ticks as we want (up to 1/30th a second of processing time anyway), and *within the same frame* use "show" to show the sprite/clone and reflect the changes made until that point all at once! As for this project, each clone has a unique My ID variable and one "when I receive" script for repeatedly moving forward (up/down) 1 step over 10 ticks. The main sprite sets a global Target ID variable to each of the clone IDs, then broadcast-and-waits the message; then each of the clones respond, and only one of them sees its ID matches, so one by one, each clone gets a turn to run its script. (If you're wondering "why not have the clones all move together at the same time?", well, yes, it's not strictly relevant for this example :P But making only one clone respond at a time is common for all sorts of games and projects, especially if the clone changes some global variable which the broadcaster is going to then make use of. Making the clones respond one by one also makes the animation and what's going on clearer when you toggle the check mark.) Once you click the check mark beside "Hide at start of animation?", each clone will also run the "hide" block before doing its "repeat 30: move 1 steps" loop. Note that the script doesn't have a corresponding "show" block! That's because... ...After all the clones have taken their turn responding to the animation broadcast, the main sprite sends out one more broadcast: "show clones". That just shows each of the clones, all at the same time. See how the sprites all move quickly, and in unison (together), when you check it? Since the clones are hidden during their animation script, Scratch doesn't make a refresh request after "move 1 steps". Now, it IS still yielding—but because there's no refresh request, Scratch runs the next tick right away! That makes them go really quickly (10 times the speed, because the "repeat 10" is happening all at once instead of over the course of 10 frames). And they all move together because there's no screen refresh between each iteration of the main "set target ID, broadcast run code" loop, either: the only screen refresh happens at the very end, when the sprites show, which always requests a refresh. The implications of this are pretty big, because this means we have a really easy way to do all sorts of normal rendering behavior without causing a screen refresh like those blocks normally do. And because there's no screen refreshes being requested, each tick happens after the previous instantaneously, and we can use "broadcast and wait" and similar blocks without any concern for the 1/30th second screen refresh delay—and all without any major changes to the way we write animation code! (PS: Scratch's source code uses the terminology "request redraw", because really it's indicating that the rendering library, scratch-render, should run its draw procedure at the point the tick ends. I'm using the slightly different phrasing "screen refresh" because that's the name Scratch's custom block maker uses: see the "run without screen refresh" toggle!)

Project Details

Project ID596883630
CreatedNovember 7, 2021
Last ModifiedNovember 7, 2021
SharedNovember 7, 2021
Visibilityvisible
CommentsAllowed