Scratch for existing programmers
Introduction
The Scratch language is a beginners programming language which is targeted primarily at the young and emphasises ease of manipulating sprites and sounds to create simple games.
The focus on sprites and games makes it easy to overlook the more important aspects of the language. These are objected oriented programming and event driven interfaces which are the foundation of the current generation of programming languages.
Most books and articles about Scratch are aimed at teaching the language to someone who is new to programming so the emphasis is on learning how to use variables, loops and conditional statements to control the behaviour of sprites.
These notes are for programmers who are learning Scratch so that they can help people who are learning Scratch as their first language. A good introduction to the Scratch IDE and language can be found here Scratch Essentials - The MagPi Magazine
Sprites
Sprites are the fundamental elements of scratch. They hold their own variables and code and mutliple instances of the same sprite can be created. Therefore sprites are effectively classes. However, because the first instance of a sprite is created automatically and you get nothing back when you create a clone of a sprite, this no equivalent of an object reference for a sprite. This in turn means that no variable or code inside a sprite can be accessed from outside of the sprite. i.e. all sprite variables and code are private.
Invoking code in a sprite
An obvious question is how code in one sprite can instruct another sprite to perform an action when sprites do not have references. The answer is that communication between sprites is done by global variables and event messages that are broadcast to all instances of all sprites.
The developer can create named messages. These messages are explicitly broadcast by code in one sprite and recieved by all sprites. These messages have only a name and no parameters. If values must be sent to go with the message then these must be saved in global variables. Any values to be returned as a result of the message must also be saved in global variables.
Messages can be sent either asynchrously using "broadcast" or synchrously using "broadcast and wait". The broadcast and wait method should be used if the message broadcast message must have been acted on before the current code cantinue e.g. it has to wait for a result to be saved in a global variable.
Event handlers
The execution of any code in a sprite occurs as a result of the sprite receiving an event. Event handlers only to be written for those events the sprite wants to respond to.
There are predefined events that are broadcast automatically to all sprites by the Scratch runtime e.g.
- green flag - sterts the program
- key press
- sprite is clicked
- the background is changed
- the microphone sound exceeds a set level
- a clone is started
Note: the clone started event is an exception in that it is only sent to the clone that is being created instead of being broadcast to all sprites.
Code blocks
The code in an event handler can be broken down into a number of named code blocks for reuse within the same sprite or for increasing readability of the code. A code bloack can created using "Make a block" in the "My blocks" section of the blocks palette and is effectively a private method. Unfortunately named blocks do not take parameters or return values. Global veriable would have to be used for this purpose.
Variables
Variables MUST be declared before they can be used and can only be used in code by dragging them from a list of existing variables.
Variables have only two types - "variable" and "list".
- "variable" - holds a number or string
- "list" - is an array of numbers and strings
Each variable or list can be:
- "For all sprites" - a global variable visible to all instances of all sprites
- "For this sprite only" - an instance variable visible on to a single instance of a sprite i.e. private
There is no equivalent to a class static variable i.e. visible to all instances of a particular sprite but not to other sprites.
Note: The blocks for maniulating lists are not displayed in the block palette until you create your first list type variable.
Note: The contents of variables and lists are NOT purged when the stop button is pressed, so it is important to clear these wherever the program starts e.g. in the green flag event handler.
Debugging
Global variables can be displayed on the stage by ticking the box next to the variable name in data section on the blocks palette.
Instance variables can be viewed by having the instance of the sprite display them using a "say" block.
Deleting a block
Deleting a block is not intuitive. First you need to drag the block to delete away from the other blocks in the code. Often the blocks below the one you drag move with it. This is not avoidable. Drag the blocks to be kept back to where they belong by dragging the top most of them. Delete the unwanted block by dragging it back to the block palette.
Starting and stopping a program
It is worth noting that unlike most languages, Scratch does not define a single point like "main" where code begins executing. Several sprites could have events handlers listening for the same first event e.g. the green flag clicked event. This means execution could begin in several sprites at the same time.
Most Scratch programs are considered to begin execution when the green flag is clicked and end when the red stop button is clicked. However, there are exceptions. The first execution of code may be in response to a mouse click, keystroke, microphione volume or on a Raspberry Pi a GPIO input. There may be no green flag event handlers at all. The red stop button halts any currently running code. It does not reset any variables or delete any sprites or their clones. Any event can start code executing again using value as they were when the stop was clicked.
Giving clones ID's
There may be occasions where you have multiple instances (clones) of a sprite and must instruct a specifc instance to perform an action. One way of doing this is:
Create the sprite and it's clones like this
- give the sprite a private (for this sprite only) variable for storing an ID
- save a new ID into a global variable
- use the "Create clone of" block to create a new clone
- create a "When I start as a clone" event handler for the sprite
- In this event handler copy the ID from the global variable into the private ID variable.
Note: Curiously the "When I start as a clone" block is under "Controls" instead of "Events"
Send a message to be acted on by a specific clone like this:
- Save the ID of the clone to act in a global variable
- Braodcast a message
- Have the event handler for the message test if the private ID variable matches the ID in the global variable.
Examples of what can be done in Scratch
There are some excellent Scratch projects shared on scratch.mit.edu which show the potential of the Scratch system. These shared projects allow you to see the code inside the project using the "see inside" button so others can learn how they are written.
Here are some examples:
- "Galaga" by RokCoder
- "Dungeon Scratcher 2" by _Milamber_
Note: These appear to be written by experienced programmers who have put considerable time and effort into their projetcs. Don't expect beginners to achieve similar results.
Advantages
- Above all ease of use
- Teaches object orientated coding by grouping data and code into objects - sprites
- Teaches creating multiple objects of the same type - clones
- Teaches event driven programming
- Teaches declaring variables before use. Many mainstream language fail to do this!
- Teaches arrays
- Teaches commom operators and functions
- Teaches building expressions from numbers, strings and variables
- Teaches if else conditional code
- Teaches user input from mouse and keyboard
- Teaches string handling
- The indentation of code enforced by the shapes of the if else and loop block should help moving to other languages
- Easy to use graphic manipulation
- Avoids syntax errors by dragging and dropping code from a palette
Limitations
Clearly the designers of Scratch could not put in all the features of a modern object orientated language, because this would sacrifice the simplicity required for their target audience. However, it is worth being aware of what they choose to leave out and what limitations this has led to.
- No object references makes all code and data in a sprite private
- Broadcast to all objects used to commincate even with a single object
- Code blocks do not have parameters
- Code block do not have return values
- Code blocks do not have local variables
- Messages do not have parameters
- The only loop structures are forever and repeat until, but other common loop structures can be built using these
- File handling is not supported so no output can be saved
- Exception handling is not supported