Event-based programming is programming in which the code is based on events, which are similar to message broadcasts. For example, a "when mouse moved" event can trigger all scripts when the mouse is moved. Events have their own attributes, called event attributes. For example, When mouse moved can have the attributes current mouse x position, previous mouse x position, distance moved, etc.
A type of Hat Block, Event Blocks, create an event listener which will run the attached code upon the event triggering. There are the four built-in events in Scratch:
Workarounds for Events
These tutorials will give scripts for the main events:
- Mouse moved
- Mouse down/up/clicked
- Any key pressed/up/down
- Format of an event
A mouse moved event is not pre-programmed in Scratch but can be easily replicated. In other programming languages, this event triggers specific lines of code to execute when the mouse moves. The mouse does not necessarily need to move over a particular object. Movement over a particular object is often referred to as "hover" and is commonly used in CSS.
In Scratch, a simple script that checks if the mouse has been moved works as follows:
when gf clicked forever set [lastMouseX v] to (mouse x) set [lastMouseY v] to (mouse y) wait (0) secs //frame pause so the condition is not checked in the same frame if <not <<(mouse x) = (lastMouseX)> and <(mouse y) = (lastMouseY)>>> then ... end
This event required no lists. It is a bundle of three events:
- Mouse down
- Mouse up
- Mouse clicked (down for less than 0.4 seconds)
Here is the script:
when gf clicked forever wait until <mouse down?> mouse down :: custom stack wait until <not <mouse down?>> mouse up :: custom end
when gf clicked forever wait until <mouse down?> wait (0.4) secs if <not <mouse down?>> then mouse clicked :: custom else wait until <not <mouse down?>> end end
This event is the same as the mouse up/down/clicked event, but for the keyboard.
when gf clicked forever wait until <key [key v] pressed?> key down :: custom wait until <not <key [key v] pressed?>> key up :: custom
when gf clicked forever wait until <key [key v] pressed?> wait (0.4) secs if <not <key [key v] pressed?>> then key pressed :: custom else wait until <not <key [key v] pressed?>> end end
Not all programming languages are optimized for a plentiful amount of built-in events, and some cannot even multi-thread, so variables must be used in replacement of event. A variable simply stores a value, and interchanging the value of the variable can be used to trigger various looping conditions and run a sequence of code. For example, in Scratch:
when this sprite clicked ...
Can be replicated with the following code:
when gf clicked forever if <<touching [mouse-pointer v]> and <mouse down>> then ...
Both have almost exactly the same functionality, but there is one notable technical difference. Using the click event hat block (first example), suppose the sprite is clicked a second time while the script is still running. Rather than the same script running two instances in parallel, the script will be interrupted and start from the beginning again. This can result in undesirable results.
The second example will not be interrupted, meaning that if the sprite is clicked while the script is being executed, the script will have to finish. Once the script finishes, it will wait until the sprite is clicked again, even if the sprite was clicked while the script was running. In conclusion, the event-based method is better for an interruption-allowing script, whereas the variable-based method is better for a script that needs to entirely execute on the variable-based virtual event.
Having the same script run in multiple instances on Scratch would require an even more hefty process, as neither variable or event-based switch logic could accomplish this with simplicity in Scratch. It would require a lot of complexity that allows scripts to optimize themselves to recognize multiple virtual threads.