Sprites¶
Sprites are the things in a project that appear on the stage, move about, and generally perform actions. Most projects will have at least one sprite.
You control how a sprite moves and acts by writing scripts. Each sprite can also have costumes and sounds that control how it looks and sounds.
Each sprite has methods which are commands that you can issue to get a sprite to do something. You also write your own methods to say how your sprite should behave, in two ways:
A method which should run every time some event happens, for example when the green flag is clicked. See Scratch hat blocks → Pytch decorators for details of how this works.
A method which your code will use internally. These are the equivalent of the custom blocks you can define in Scratch.
Creating Sprites¶
You can create a Sprite in your project by declaring a Python class that uses the Sprite as a foundation. You do this by creating a class with some name (for example, “Kitten”), and mentioning the pytch Sprite class as its basis. Here is an example of a Kitten class that has a single costume (costumes are discussed just below):
import pytch
class Kitten(pytch.Sprite):
Costumes = ["happy-kitten.jpg"]
Saying how a sprite should behave¶
In Scratch you put together scripts which say how you want your Sprite to behave when certain things happen, for example, when that Sprite is clicked. In Pytch, you do this by writing your own methods on your class. For example,
import pytch
class Spaceship(pytch.Sprite):
@pytch.when_key_pressed("ArrowUp")
def move_up(self):
self.change_y(10)
Here we see:
The method decorator
pytch.when_key_presseddoes the job of a Scratch hat block — Pytch’s decorators are described in their own section of the documentation.The method call
self.change_y(10)does the job of the change y by Scratch block — a Pytch sprite’s methods are described below.
Controlling how scripts run¶
You can pause a script, send messages to launch other scripts, and stop all scripts in your program:
Pausing a script¶
- self.wait_seconds(n_seconds)¶
Make the script calling
wait_seconds()do nothing forn_secondsseconds before resuming. This is done by counting frames, so complicated scripts which render at less than 60fps will wait for the wrong amount of time; fixing this is on the roadmap.
Broadcasting messages¶
- self.broadcast(message_string)¶
Broadcast the message
message_string, launching any scripts with a matching@pytch.when_I_receive()decorator (hat-block). The script callingbroadcast()continues, with the responding scripts running concurrently.
- self.broadcast_and_wait(message_string)¶
Broadcast the message
message_string, launching any scripts with a matching@pytch.when_I_receive()decorator (hat-block). The script callingbroadcast_and_wait()waits until all those responding scripts have finished before continuing.
Stopping all scripts¶
- self.stop_all()¶
Stop all currently-executing scripts. Also stop all sounds, delete all clones, abandon all “ask and wait” questions, and clear all speech bubbles.
stop_all()does the same job as the “red stop” button.
Controlling how a sprite looks¶
Each sprite can have a collection of Costumes that control how it looks. The first costume mentioned will be how the sprite first appears and you can change the Sprite’s appearance using commands.
If a Sprite is to appear on the stage then it has to have at least one costume (it’s OK for a sprite to be invisible, and then it doesn’t need to have any costumes at all). Costumes are controlled by a variable in each Sprite that lists the images that the Sprite can have. To use an image you have to upload it to your project, and then you can add it to your Sprite’s list of available Costumes.
You can read the details of how you list costumes in the assets document.
Usually all you have to do is make a list called Costumes in the sprite and list all the names of the uploaded files you want to use.
This list has to be set up as the Sprite is created (Pytch can’t yet load more images after the sprite has been set up).
The Costumes variable needs to be declared inside the Sprite. For example, here is a definition for a new Sprite class that will have two costumes:
class Kitten(pytch.Sprite):
Costumes = ["smiling-kitten.jpg",
"frowning-kitten.jpg"]
By default the Sprite will use the first image as its appearance. If you
want to change to another costume you can use the switch_costume()
method.
- Setting the sprite size
- self.set_size(size)¶
Set how large the sprite appears, as a proportion of the size of the current costume image, where
1is the normal size of the image. For example,self.set_size(0.5)will set the sprite to be half-sized.
- Finding out the sprite’s size
- self.size¶
The current size of the Sprite, where
1is normal size,0.5is half-size,2is double-size, and so on.
- Showing and hiding the sprite
- Changing the sprite appearance
- self.switch_costume(name)¶
Select one of the costumes listed in this Sprite’s Costumes variable. The name is the costume’s label, which is usually the filename without the extension (see Defining costumes for full details). For example, you might use
self.switch_costume("smiling-kitten")to choose a new costume.
- self.switch_costume(costume_number)
Select one of the costumes listed in this Sprite’s Costumes variable, by number. Python starts counting entries in lists at zero, so to switch to the first costume, you would use
self.switch_costume(0); to switch to the second costume, you would useself.switch_costume(1), and so on.
- self.next_costume()¶
Switch to the costume after the current one. If the Sprite is wearing the last costume in its
Costumeslist, then go back to the first one in the list.
- self.next_costume(n_steps)
Switch to the costume
n_stepsafter the current one. If this would take the Sprite beyond the end of itsCostumeslist, then wrap round to the first entry again, as if the costumes were in a circle. You can use a negative number forn_stepsto choose an earlier costume in the list. For example,self.next_costume(-1)will switch to the previous costume.
- Finding out what costume the Sprite is currently wearing
- self.costume_number¶
The zero-based number of the costume currently being worn by the Sprite. Here, ‘zero-based’ means that the first costume in the
Costumeslist is number 0; the second costume is number 1; and so on. This is the way that Python refers to list elements.
- self.costume_name¶
The name of the costume currently being worn by the Sprite.
- Controlling the order Sprites are drawn
When one sprite overlaps another it is the order that they are drawn that controls what you see. Sprites on the back layer are drawn first, and then Sprites from the next layer are drawn on top of that, and so on until the front layer is reached. By moving sprites between layers you can control which Sprites appear on top.
Moving a Sprite¶
Sprites can move their position on the stage using these motion commands. There is an exact x and y position on the stage where the “origin” of the sprite is. Normally the origin in the exact middle of the sprite’s current costume, but you can change the origin when you are creating the costume (see here)
- self.go_to_xy(x, y)¶
Move the sprite to a particular position on the stage.
- self.go_to_mouse()¶
Move the sprite to the position of the mouse pointer.
- self.glide_to_xy(x, y, seconds)¶
Glide the sprite smoothly to a particular position on the stage, taking the given number of seconds to do so. The value for
secondsdoes not have to be a whole number. Advanced/experimental: You can also give a fourth argument, to give the easing of the glide. This can be: the string"linear", to move at a constant speed; or the string"ease-in-out", to start slowly, speed up, then slow back down as the glide finishes.
- self.glide_to_mouse(seconds)¶
Glide the sprite smoothly to the position of the mouse pointer, taking the given number of seconds to do so. The value for
secondsdoes not have to be a whole number. Advanced/experimental: You can also give a second argument, to give the easing of the glide. This can be: the string"linear", to move at a constant speed; or the string"ease-in-out", to start slowly, speed up, then slow back down as the glide finishes.
- self.change_x(dx)¶
Change the x-position of the sprite by a certain amount (for example,
self.change_x(10)will move the sprite 10 pixels to the right on the stage). The number of pixels can be negative.
- self.change_y(dy)¶
Change the y-position of the sprite by a certain amount (for example,
self.change_y(10)will move the sprite 10 pixels up on the stage). The number can be negative.
- self.set_x(x)¶
Move the sprite to a certain x-position on the stage while keeping its y-position the same.
- self.set_y(y)¶
Move the sprite to a certain y-position on the stage while keeping its x-position the same.
Finding a Sprite’s position¶
Turning a Sprite¶
A sprite can turn round and point in different directions.
Warning
This feature is experimental. Currently, the touching()
results (see Checking for sprites colliding) will be inaccurate if a
sprite has turned from its starting direction. Also,
when_this_sprite_clicked events will not be accurately
detected.
- self.turn_degrees(angle)¶
Turn the sprite by the given angle (measured in degrees), in an anticlockwise (counter-clockwise) direction. To turn clockwise, use a negative value for
angle. This is the opposite convention to Scratch, but “positive is anticlockwise” is the common mathematical convention, so Pytch uses it.
- self.point_degrees(angle)¶
Turn the sprite so it is pointing in the direction of the given angle (measured in degrees). An angle of zero means that the sprite is drawn the same way up as the original image for the costume it’s currently wearing. An angle of 90° means the sprite points a quarter-turn anticlockwise (counter-clockwise) from its original image. To point a quarter-turn clockwise, use −90° (or 270°, which comes to the same thing).
- self.point_towards_mouse()¶
Turn the sprite so it is pointing towards the mouse pointer.
- self.direction¶
The direction the sprite is currently pointing, measured in degrees.
Making sounds¶
Sounds have to be loaded into the Sprite when it is created (see Defining sounds). Once a sound has been loaded you can get the sprite to play it.
- self.start_sound(sound_name_or_index)¶
Start a sound playing. You refer to the sound in one of two ways. You can use its label, which is usually the filename without the extension (see Defining sounds for full details), or you can use its index, which is the zero-based position of the required sound in the Sprite’s list of sounds. Once the sound has started the Sprite will move on to its next instruction.
- self.play_sound_until_done(sound_name_or_index)¶
Start a sound playing. You can refer to the sound using its label or its index, as for
start_sound(). This method will not return until the entire sound has played, so the script it is contained in won’t do its next instruction until then.
- self.stop_all_sounds()¶
Immediately stop all sounds from playing, including those being played by the Stage or by other Sprites.
Sensing¶
- self.key_pressed(key_name)¶
Give a
True/Falseanswer as to whether the key with namekey_nameis currently pressed.
Making and deleting copies of a Sprite¶
Each Sprite is created on the Stage at the start of the program, but it is possible to create further copies of each Sprite when the program is running. These copies are called “clones” of the original.
When a clone is created it starts at the same position and wearing the same costume as the original, but it can run its own scripts to change its behaviour. The “self” variable always refers to the current clone.
Creating new clones¶
Clones can be created in two ways. Quite often, you just want to create a clone of the sprite which is running the code. In this case, you can use the simple version:
- self.create_clone()¶
Create a new clone of
self.
There is more general version if you want to create a clone of something else:
- self.create_clone_of(thing)¶
Create a new clone of
thing. You can create clones in two ways. You can clone the original or an existing clone of one of your Sprites, for example a Sprite clone which is calling thecreate_clone_of()function:self.create_clone_of(self)
(Although in this case you can use the simpler
self.create_clone().)Or you can create a clone of a particular class of Sprite:
self.create_clone_of(Spaceship)
In this case, Pytch makes a clone of the original instance of that sprite.
You can also clone any instance of any sprite. For example, if you know there are at least three clones of a
Spidersprite, you can create a clone of the third one with:self.create_clone_of(Spider.all_clones()[2])
You can not clone your Stage.
Deleting clones¶
- self.delete_this_clone()¶
Remove the current clone. If this method is run by the original sprite then it has no effect at all. If it is run by a clone, then the clone vanishes at the end of the current frame, and execution of the handler which called
delete_this_clone()is halted.
Finding existing clones¶
- Class.the_original()¶
This returns a reference to the original object that this clone is a copy of. This can be used to look up variables or send messages to the original object. If it is run by the original Sprite then it returns a reference to itself. Notice that this method is run using the class name (for example
Kitten.the_original()), not theselfobject.
- Class.all_clones()¶
Returns a list of all the existing clones of the Sprite that is mentioned (for example
Kitten.all_clones()). Notice that this method is run using the class name (for exampleKitten.all_clones()), not theselfobject.
- Class.all_instances()¶
Like
all_clones, this returns a list of all clones of the Sprite that is mentioned (for exampleKitten.all_clones()), butall_instancesalso includes the original Sprite in the list. This is useful if you want access to everything (both clones and originals). Notice that this method is run using the class name (for exampleKitten.all_instances()), not theselfobject.
Checking for sprites colliding¶
- self.touching(target_class)¶
You can use this method to check whether this sprite is touching any instance of another class. For example
self.touching(Dog)will return either True or False depending on whether the current Sprite is overlapping aDogsprite.At the moment Pytch does not look at the actual image in the costume, just its overall size, so if the two costumes have blank sections but the costumes themselves are overlapping then this method will still return true. The current costume and the size set by
set_sizeis taken into account when checking.Note that you check using a class name, so if the
selfsprite is touching any clone of the target class thentouchingwill return true.
Showing and hiding speech bubbles¶
Speech bubbles can be used to get Sprites to show some text on the Stage.
- self.say(content)¶
Show a speech bubble next to the current Sprite, showing the text supplied. For exampler
self.say("Hello there"). If the Sprite usesself.hide()to disappear from the stage then the bubble will also disappear. If the Sprite then re-appears (by usingself.show()), then the speech bubble will also re-appear.To remove a Sprite’s speech bubble, use the empty string for the
contentargument, as in:# Remove speech bubble: self.say("")
- self.say_for_seconds(content, seconds)¶
Show a speech balloon, wait for the number of seconds given, and then remove it. The whole script will wait while the balloon is being shown. If a second script calls
say_for_seconds()while a first script is already in the middle ofsay_for_seconds(), the second script’s speech replaces the first script’s speech.
Showing and hiding a sprite’s variables¶
- self.show_variable(variable_name)¶
In Scratch, you can “show” a variable, either by ticking a box in the UI, or by using the show variable MY-VARIABLE block. Pytch does not have a box to tick, but you can show a sprite’s (or the stage’s) variable with the
self.show_variable()function. The argument is the name of the sprite’s (or stage’s) variable, which means you will often want to give a quoted string, for example:self.show_variable("score")
(There is a more general version available; see its documentation for details.)
- self.hide_variable(variable_name)¶
Remove the variable watcher for the variable called
variable_name. It is not an error if there is not currently such a watcher. (There is a more general version available; see its documentation for details.)
Asking the user a question¶
Pytch has a method matching Scratch’s ask and wait block. In
Scratch, you can find what the user typed using the answer reporter
block. In Pytch, the user’s answer is returned to your program from
the ask_and_wait() method.
- self.ask_and_wait(question)¶
Ask the question, and pop up an input box where the user can type their answer. If the Sprite is currently shown, the question is asked with a speech bubble. If the Sprite is hidden, the question is asked as part of the input box.
Your method is paused while the user is typing their answer, and will continue once the user submits their answer. The answer is returned, so you will usually assign it to a variable. For example, this code assigns the user’s answer to a variable
nameand then greets the user:class Banana(pytch.Sprite): # [ ... Costumes, Sounds, other methods, etc. ... ] @pytch.when_this_sprite_clicked def ask_user_their_name(self): name = self.ask_and_wait("What's your name?") self.say(f"Hello, {name}!")