EktuPy API Reference
Complete reference for all EktuPy classes, methods, and functions.
Table of Contents
- Stage Class
- Sprite Class
- Eggs
- Global Event Decorators
- Control Functions
- Input Functions
- Sensing Functions
- Messaging
- Sound Functions
- Asset Map
Stage Class
The Stage is the canvas where all sprites live and move. The stage has a fixed size of 960x720 pixels.
Constructor
Stage(background_color="#ffffff")
| Parameter | Type | Default | Description |
|---|---|---|---|
background_color | str | “#ffffff” | Background color (CSS color) |
# Create a stage with default white background
stage = Stage()
# Create a stage with a custom background color
stage = Stage("#1a1a2e")
Properties
| Property | Type | Description |
|---|---|---|
width | int | Stage width (always 960) |
height | int | Stage height (always 720) |
Coordinate System
EktuPy uses a Scratch-like coordinate system with the origin at the center:
(0, 360) Top
|
|
(-480, 0) Left -----(0, 0)-----> (480, 0) Right
|
|
(0, -360) Bottom
| Axis | Range | Description |
|---|---|---|
| X | -480 to 480 | Horizontal position (negative = left, positive = right) |
| Y | -360 to 360 | Vertical position (negative = down, positive = up) |
Direction angles:
0= Up90= Right180(or-180) = Down-90= Left
Methods
set_background(color)
Set the stage background color.
stage.set_background("#87CEEB") # Sky blue
stage.set_background("red") # Named color
set_background_image(name_or_path)
Set a background image by asset name or path.
# Using an asset name
stage.set_background_image("sky-and-clouds")
# Using a path
stage.set_background_image("/static/assets/backdrops/jungle.svg")
Available backdrops:
jungle- Dense jungle forest scenemountain-sunrise- Mountains with rising sunpaddy-field- Sun over rice paddy fieldsrace-track- Racing track scenesky-and-clouds- Blue sky with fluffy clouds
set_cursor_sprite(sprite)
Set a sprite to use as a custom mouse cursor. The sprite will follow the mouse position and render on top of everything. The default cursor is hidden while inside the stage area.
# Create a custom cursor
hammer = Sprite("hammer")
hammer.size = 50
stage.set_cursor_sprite(hammer)
# Restore default cursor
stage.set_cursor_sprite(None)
| Parameter | Type | Description |
|---|---|---|
sprite | Sprite or None | Sprite to use as cursor, or None to restore default |
Example: Whack-a-Mole with hammer cursor
stage = Stage()
hammer = Sprite("hammer")
hammer.size = 60
stage.set_cursor_sprite(hammer)
# The hammer now follows the mouse automatically
add_sprite(sprite)
Add a sprite to the stage.
cat = Sprite("cat")
stage.add_sprite(cat)
add_egg(egg)
Add an egg (special display element) to the stage. See Eggs for available egg types.
from ektupy import SegmentDisplay
display = SegmentDisplay(cells=8, color="#00FF00")
stage.add_egg(display)
start()
Start the game loop. Usually called automatically.
stop()
Stop the game loop.
Sprite Class
Sprites are the visual objects that move and interact on the stage.
Constructor
Sprite(image_path=None)
| Parameter | Type | Default | Description |
|---|---|---|---|
image_path | str | None | Asset name or path to sprite image (SVG, PNG, etc.) |
You can create sprites using either an asset name (simpler) or a full path:
# Using asset name (recommended)
snake = Sprite("snake") # Looks up "snake" in the asset map
paddle = Sprite("paddle") # Looks up "paddle" in the asset map
# Using full path (also works)
snake = Sprite("/static/assets/sprites/snake.svg")
Asset names are easier to use and will show a warning in the editor if the name doesn’t exist. See Asset Map for more details.
Sprite Properties
All properties can be read and written:
| Property | Type | Description |
|---|---|---|
x | float | X position (0 = center) |
y | float | Y position (0 = center) |
direction | float | Direction in degrees (0=up, 90=right) |
size | float | Size as percentage (100 = normal) |
costume_number | int | Current costume number (read-only) |
costume_name | str | Current costume name (read-only) |
is_clone | bool | True if this sprite is a clone (read-only) |
sprite.x = 100
sprite.y = -50
sprite.direction = 90 # Face right
sprite.size = 150 # 150% size
print(sprite.x) # Read position
Motion Methods
move(steps)
Move in the current direction.
sprite.move(10) # Move 10 steps forward
turn_right(degrees) / turn_left(degrees)
Rotate the sprite.
sprite.turn_right(90) # Turn 90 degrees clockwise
sprite.turn_left(45) # Turn 45 degrees counter-clockwise
go_to(x, y)
Instantly move to a position.
sprite.go_to(0, 0) # Go to center
sprite.go_to(-100, 50) # Go to specific position
set_x(x) / set_y(y)
Set just the x or y position.
sprite.set_x(100)
sprite.set_y(-50)
change_x(amount) / change_y(amount)
Change position by an amount.
sprite.change_x(10) # Move 10 pixels right
sprite.change_y(-5) # Move 5 pixels down
go_to_random_position()
Move to a random position on the stage.
sprite.go_to_random_position()
go_to_mouse()
Move to the mouse pointer position.
sprite.go_to_mouse()
go_to_sprite(other)
Move to another sprite’s position.
cat.go_to_sprite(dog)
glide_to(x, y, seconds)
Smoothly glide to a position over time.
sprite.glide_to(100, 50, 2) # Glide over 2 seconds
glide_to_random_position(seconds)
Glide to a random position.
sprite.glide_to_random_position(1.5)
glide_to_mouse(seconds)
Glide to the mouse pointer.
sprite.glide_to_mouse(1)
glide_to_sprite(other, seconds)
Glide to another sprite.
cat.glide_to_sprite(dog, 2)
point_towards(x, y)
Point toward a position.
sprite.point_towards(100, 100)
point_towards_mouse()
Point toward the mouse pointer.
sprite.point_towards_mouse()
point_towards_sprite(other)
Point toward another sprite.
cat.point_towards_sprite(dog)
set_rotation_style(style)
Set how the sprite rotates visually.
| Style | Description |
|---|---|
"all around" | Rotate freely in all directions |
"left-right" | Only flip horizontally (default) |
"don't rotate" | Never rotate visually |
sprite.set_rotation_style("all around")
bounce_if_on_edge()
If touching edge, bounce (reverse direction).
@on_forever
def move():
sprite.move(5)
sprite.bounce_if_on_edge()
Looks Methods
say(text, seconds=None)
Show a speech bubble.
sprite.say("Hello!") # Show until changed
sprite.say("Hi!", 2) # Show for 2 seconds
sprite.say("") # Clear bubble
think(text, seconds=None)
Show a thought bubble (cloud shape).
sprite.think("Hmm...")
sprite.think("I wonder...", 3)
show() / hide()
Show or hide the sprite.
sprite.hide()
wait(1)
sprite.show()
change_size(amount)
Change size by amount.
sprite.change_size(10) # Grow by 10%
sprite.change_size(-20) # Shrink by 20%
set_ghost_effect(value)
Set transparency (0=visible, 100=invisible).
sprite.set_ghost_effect(50) # 50% transparent
change_ghost_effect(amount)
Change transparency by amount.
sprite.change_ghost_effect(10) # More transparent
clear_graphic_effects()
Reset all visual effects.
sprite.clear_graphic_effects()
switch_costume(name_or_index)
Switch to a different costume.
sprite.switch_costume(0) # By index
sprite.switch_costume("walk1") # By name
next_costume()
Switch to the next costume (wraps around).
sprite.next_costume()
add_costume(image_path, name)
Add a new costume from an image.
sprite.add_costume("/static/assets/walk2.png", "walk2")
Layer Methods
sprite.go_to_front_layer() # Move to front
sprite.go_to_back_layer() # Move to back
sprite.go_forward_layers(2) # Move forward 2 layers
sprite.go_backward_layers(1) # Move backward 1 layer
Rotation and Flip Methods
These methods let you visually rotate and flip sprites independently of their movement direction. Unlike direction (which controls which way the sprite moves), these methods only affect how the sprite looks.
set_rotation(degrees)
Set the visual rotation of the sprite in degrees. This rotates the sprite’s image without changing its movement direction.
sprite.set_rotation(45) # Rotate 45 degrees clockwise
sprite.set_rotation(0) # Reset to no rotation
sprite.set_rotation(-90) # Rotate 90 degrees counter-clockwise
| Parameter | Type | Description |
|---|---|---|
degrees | float | Rotation angle in degrees (positive = clockwise) |
Example: Spinning coin animation
coin = Sprite("coin")
@on_forever
def spin_coin():
coin.change_rotation(5) # Continuously spin
change_rotation(degrees)
Change the visual rotation by a relative amount.
sprite.change_rotation(10) # Rotate 10 degrees more clockwise
sprite.change_rotation(-15) # Rotate 15 degrees counter-clockwise
| Parameter | Type | Description |
|---|---|---|
degrees | float | Amount to change rotation (positive = clockwise) |
Example: Tilt on key press
spaceship = Sprite("spaceship")
@on_key_press("left arrow")
def tilt_left():
spaceship.change_rotation(-15)
@on_key_press("right arrow")
def tilt_right():
spaceship.change_rotation(15)
flip_horizontal()
Toggle the horizontal flip state. If the sprite is normal, it flips horizontally (mirror image). If already flipped, it returns to normal.
sprite.flip_horizontal() # Flip left-right
Example: Face direction of movement
player = Sprite("robot")
@on_key_press("left arrow")
def move_left():
if not player.is_flipped_horizontally:
player.flip_horizontal() # Face left
player.change_x(-10)
@on_key_press("right arrow")
def move_right():
if player.is_flipped_horizontally:
player.flip_horizontal() # Face right
player.change_x(10)
flip_vertical()
Toggle the vertical flip state. If the sprite is normal, it flips vertically (upside down). If already flipped, it returns to normal.
sprite.flip_vertical() # Flip upside-down
Example: Flip when hit
enemy = Sprite("alien")
def on_hit():
enemy.flip_vertical() # Turn upside down when defeated
set_flipped_horizontally(flipped)
Explicitly set whether the sprite is horizontally flipped.
sprite.set_flipped_horizontally(True) # Force flip
sprite.set_flipped_horizontally(False) # Force normal
| Parameter | Type | Description |
|---|---|---|
flipped | bool | True to flip horizontally, False for normal |
Example: Always face the mouse
cat = Sprite("cat")
@on_forever
def face_mouse():
# Flip based on mouse position
cat.set_flipped_horizontally(mouse_x() < cat.x)
set_flipped_vertically(flipped)
Explicitly set whether the sprite is vertically flipped.
sprite.set_flipped_vertically(True) # Force upside-down
sprite.set_flipped_vertically(False) # Force normal
| Parameter | Type | Description |
|---|---|---|
flipped | bool | True to flip vertically, False for normal |
Note: You can also read the current flip state using:
sprite.is_flipped_horizontally- ReturnsTrueif horizontally flippedsprite.is_flipped_vertically- ReturnsTrueif vertically flipped
Pen Methods
Draw lines on the stage as the sprite moves.
pen_down() / pen_up()
Start or stop drawing.
sprite.pen_down()
sprite.move(100) # Draws a line
sprite.pen_up()
sprite.move(50) # No line drawn
set_pen_color(color)
Set the pen color.
sprite.set_pen_color("red")
sprite.set_pen_color("#FF5500")
sprite.set_pen_color("rgb(255, 100, 0)")
set_pen_size(size)
Set the pen width in pixels.
sprite.set_pen_size(5)
stamp()
Stamp the sprite’s image onto the stage.
sprite.stamp()
clear()
Erase all pen drawings.
sprite.clear()
Sensing Methods
touching(other)
Check if touching another sprite.
if cat.touching(dog):
cat.say("Ouch!")
touching_edge()
Check if touching the stage edge.
if sprite.touching_edge():
sprite.bounce_if_on_edge()
touching_mouse()
Check if touching the mouse pointer.
if sprite.touching_mouse():
sprite.say("You're on me!")
distance_to(other)
Get distance to another sprite.
dist = cat.distance_to(dog)
if dist < 50:
cat.say("Too close!")
distance_to_mouse()
Get distance to the mouse pointer.
dist = sprite.distance_to_mouse()
if dist < 100:
sprite.say("Getting close!")
Clone Methods
Create copies of sprites at runtime.
clone()
Create a clone of this sprite.
new_clone = sprite.clone()
on_clone_start(callback)
Register a function to run when this sprite is cloned.
def on_cloned():
# 'sprite' here refers to the new clone
sprite.go_to_random_position()
sprite.on_clone_start(on_cloned)
delete_clone()
Delete this clone (only works on clones).
if sprite.is_clone:
sprite.delete_clone()
Per-Sprite Event Decorators
Each sprite can have its own event handlers, just like Scratch.
@sprite.on_start
Runs when the program starts (for this sprite only).
@cat.on_start
def cat_setup():
cat.go_to(-100, 0)
cat.say("I'm the cat!")
@sprite.on_forever
Runs every frame (for this sprite only).
@cat.on_forever
def cat_loop():
cat.turn_right(1)
@sprite.on_key_press(key)
Runs when a key is pressed (for this sprite only).
@cat.on_key_press("space")
def cat_jump():
cat.change_y(50)
@sprite.on_message(message)
Runs when a broadcast is received (for this sprite only).
@cat.on_message("game_over")
def cat_dies():
cat.say("Oh no!")
cat.hide()
sprite.on_clicked(callback)
Runs when this sprite is clicked.
def on_cat_click():
cat.say("You clicked me!")
cat.on_clicked(on_cat_click)
Eggs
Eggs are special visual components that can be added to the stage but aren’t sprites. Unlike sprites, eggs don’t have movement, costumes, or collision detection - they’re specialized display elements.
SegmentDisplay
A 14-segment LED display for showing text, numbers, and scrolling messages. Perfect for scoreboards, clocks, timers, and retro-style game displays.
Constructor
SegmentDisplay(cells=4, color="#00FF00", bg_color=None, scale=1.0, panel_color="#0a0a0a")
| Parameter | Type | Default | Description |
|---|---|---|---|
cells | int | 4 | Number of character cells in the display |
color | str | “#00FF00” | Color of lit segments (CSS color) |
bg_color | str | None | Color of unlit segments (auto-calculated if None) |
scale | float | 1.0 | Scale factor for the display size |
panel_color | str | “#0a0a0a” | Background panel color |
from ektupy import Stage, SegmentDisplay
stage = Stage()
stage.set_background("#0d1117")
# Create a green 8-cell display
score_display = SegmentDisplay(cells=8, color="#00FF00", scale=1.0)
stage.add_egg(score_display)
score_display.go_to(0, 200)
score_display.show("SCORE")
Methods
show(text)
Display static text on the segment display.
display.show("HELLO") # Show text
display.show("12345") # Show numbers
display.show("HI:00") # Colons work too
display.show("99.5") # Decimal points supported
| Parameter | Type | Description |
|---|---|---|
text | str | Text to display (uppercase letters, numbers, some symbols) |
Supported characters:
- Letters: A-Z (uppercase, displayed as uppercase)
- Numbers: 0-9
- Symbols:
.:-_+=/\*!?'"()[]<>@#$%^& - Space:
scroll(text, speed=0.1)
Start scrolling text across the display automatically.
# Scroll a message (adds padding automatically)
display.scroll("WELCOME TO THE GAME", 0.15)
# Faster scrolling
display.scroll("BREAKING NEWS", 0.05)
| Parameter | Type | Default | Description |
|---|---|---|---|
text | str | - | Text to scroll |
speed | float | 0.1 | Seconds between scroll steps (smaller = faster) |
The scroll loops continuously until you call show() or stop_scroll().
stop_scroll()
Stop scrolling and clear the display.
display.stop_scroll()
go_to(x, y)
Position the display on the stage (uses Scratch-style coordinates).
display.go_to(0, 200) # Center-top
display.go_to(-300, -200) # Bottom-left area
| Parameter | Type | Description |
|---|---|---|
x | float | X position (-480 to 480) |
y | float | Y position (-360 to 360) |
hide() / show_display()
Hide or show the display.
display.hide() # Make invisible
display.show_display() # Make visible again
Example: Digital Clock
from ektupy import Stage, SegmentDisplay, on_start, on_forever
from ektupy import current_hour, current_minute, current_second
stage = Stage()
stage.set_background("#0d1117")
# Red clock display (like alarm clocks)
clock = SegmentDisplay(cells=8, color="#FF2222", scale=1.2)
stage.add_egg(clock)
clock.go_to(0, 0)
@on_forever
def update_clock():
h = current_hour()
m = current_minute()
s = current_second()
clock.show(f"{h:02d}:{m:02d}:{s:02d}")
Example: Game Score with Multiple Displays
from ektupy import Stage, SegmentDisplay, Sprite, on_start, on_key_press
stage = Stage()
stage.set_background("#1a1a2e")
# Title display - green
title = SegmentDisplay(cells=10, color="#00FF00", scale=1.0)
stage.add_egg(title)
title.go_to(0, 250)
title.show("HIGH SCORE")
# Score display - amber/orange
score_display = SegmentDisplay(cells=8, color="#FFAA00", scale=1.2)
stage.add_egg(score_display)
score_display.go_to(0, 150)
# Lives display - red
lives_display = SegmentDisplay(cells=6, color="#FF0000", scale=0.8)
stage.add_egg(lives_display)
lives_display.go_to(0, 50)
score = 0
lives = 3
@on_start
def setup():
score_display.show(f"{score:08d}")
lives_display.show(f"LIVES:{lives}")
@on_key_press("space")
def add_points():
global score
score += 100
score_display.show(f"{score:08d}")
Example: Scrolling Message
from ektupy import Stage, SegmentDisplay, on_start
stage = Stage()
stage.set_background("#0d1117")
# Cyan scrolling display
news = SegmentDisplay(cells=16, color="#00FFFF", scale=0.9)
stage.add_egg(news)
news.go_to(0, 0)
@on_start
def setup():
# Text scrolls automatically and loops
news.scroll(" WELCOME TO EKTUPY - CREATE AMAZING GAMES WITH PYTHON ", 0.12)
Global Event Decorators
These decorators register handlers that aren’t tied to a specific sprite.
@on_start
Runs once when the program starts.
@on_start
def setup():
print("Game started!")
@on_forever
Runs every frame (approximately 60 times per second).
@on_forever
def game_loop():
# Update game state
pass
@on_key_press(key)
Runs when a specific key is pressed.
Key names: "a" to "z", "0" to "9", "space", "up arrow", "down arrow", "left arrow", "right arrow", "any" (any key)
@on_key_press("space")
def jump():
player.change_y(50)
@on_key_press("any")
def any_key(key):
print(f"Pressed: {key}")
@on_mouse_click
Runs when the mouse is clicked on the stage.
@on_mouse_click
def click_handler(x, y):
print(f"Clicked at ({x}, {y})")
sprite.go_to(x, y)
@on_message(message)
Runs when a broadcast message is received.
@on_message("level_complete")
def next_level():
print("Loading next level...")
Control Functions
wait(seconds)
Pause execution without freezing the program.
@on_start
def setup():
sprite.say("Hello!")
wait(2)
sprite.say("Goodbye!")
wait_until(condition)
Wait until a condition becomes true.
@on_start
def setup():
sprite.say("Waiting for you to press space...")
wait_until(lambda: key_pressed("space"))
sprite.say("Thanks!")
stop() / stop_all()
Stop the game/program.
if game_over:
stop()
Input Functions
key_pressed(key)
Check if a key is currently held down.
if key_pressed("right arrow"):
sprite.change_x(5)
mouse_x() / mouse_y()
Get the mouse position on the stage.
x = mouse_x()
y = mouse_y()
sprite.go_to(x, y)
mouse_down()
Check if the mouse button is pressed.
if mouse_down():
sprite.stamp()
Sensing Functions
Global functions for sensing time, date, and environment.
Timer
timer()
Get the time in seconds since the program started (or since the last reset).
t = timer()
if t > 30:
sprite.say("30 seconds passed!")
reset_timer()
Reset the timer back to 0.
reset_timer()
# timer() now returns 0
Date and Time
current_year()
Get the current year.
year = current_year() # e.g., 2025
current_month()
Get the current month (1-12).
month = current_month() # 1=January, 12=December
current_date()
Get the current day of the month (1-31).
day = current_date()
current_day_of_week()
Get the current day of the week (1-7, where 1=Sunday).
day_of_week = current_day_of_week()
if day_of_week == 1:
sprite.say("It's Sunday!")
current_hour()
Get the current hour (0-23).
hour = current_hour()
if hour < 12:
sprite.say("Good morning!")
current_minute()
Get the current minute (0-59).
minute = current_minute()
current_second()
Get the current second (0-59).
second = current_second()
days_since_2000()
Get the number of days since January 1, 2000 (including fractional days).
days = days_since_2000()
sprite.say(f"{int(days)} days since Y2K!")
Ask and Answer
Get user input through an on-screen text box, just like Scratch’s “ask [] and wait” block.
ask(prompt)
Show a text input box at the bottom of the stage with a prompt, wait for the user to type and submit an answer, then return the answer as a string.
@on_start
def setup():
name = ask("What is your name?")
sprite.say(f"Hello, {name}!")
The input box appears at the bottom of the stage with:
- The prompt text displayed above the input field
- A text input where the user can type
- A submit button (or press Enter to submit)
The program pauses until the user submits their answer.
answer()
Get the most recent answer from ask(). This is useful when you need to access the last answer later in your code.
@on_start
def setup():
ask("What is your name?")
name = answer() # Get the answer that was just entered
ask("How old are you?")
age = answer() # Get this new answer
sprite.say(f"Hi {name}, you are {age} years old!")
Example: Multiple questions
@on_start
def quiz():
score = 0
ask("What is 5 + 3?")
if answer() == "8":
score += 1
sprite.say("Correct!")
else:
sprite.say("Wrong! It's 8")
wait(1)
ask("What color is the sky?")
if answer().lower() == "blue":
score += 1
sprite.say("Correct!")
else:
sprite.say("Wrong!")
wait(1)
sprite.say(f"You scored {score}/2!")
Messaging
broadcast(message, data=None)
Send a message to all listeners.
broadcast("game_over")
broadcast("score_changed", {"score": 100})
Receive with @on_message or @sprite.on_message:
@on_message("score_changed")
def update_score(data):
print(f"New score: {data['score']}")
broadcast_and_wait(message, data=None)
Send a message and wait for all handlers to complete before continuing.
# Send message and wait for all handlers to finish
broadcast_and_wait("prepare_level")
# This line runs after ALL @on_message("prepare_level") handlers complete
print("Level ready!")
Useful for synchronization:
@cat.on_key_press("space")
def start_animation():
cat.say("Ready...")
broadcast_and_wait("all_sprites_ready") # Wait for everyone
cat.say("Go!") # Only runs after all handlers finish
@dog.on_message("all_sprites_ready")
def dog_prepare():
dog.go_to(0, 0)
wait(1) # This delay is waited for by broadcast_and_wait
Console Output
Use standard Python print() for debugging:
print("Hello!") # Appears in white
print(f"Position: {x}") # String formatting works
import sys
sys.stderr.write("Error!\n") # Appears in red
Sound Functions
Play sounds and music in your projects, just like Scratch’s Sound blocks.
Loading and Playing Sounds
load_sound(name)
Load a sound by name and return a Sound object. The name is looked up in the asset map.
# Load a sound - returns a Sound object
poweron = load_sound("sfx_sound_poweron")
coin = load_sound("sfx_coin_single1")
| Parameter | Type | Description |
|---|---|---|
name | str | Asset name to look up in the sound library |
Returns: Sound - A Sound object to use with start_sound(), stop_sound(), etc.
Asset names will show a warning in the editor if the name doesn’t exist. See Asset Map for available sounds.
start_sound(sound)
Start playing a sound (like Scratch’s “play sound” block). The sound plays in the background while your code continues running.
meow = load_sound("sfx_sound_meow")
start_sound(meow) # Plays and continues immediately
sprite.say("Meow!") # Runs right away
| Parameter | Type | Description |
|---|---|---|
sound | Sound | A Sound object returned by load_sound() |
play_sound_until_done(sound)
Play a sound and wait until it finishes (like Scratch’s “play sound until done” block).
meow = load_sound("sfx_sound_meow")
@on_start
def setup():
sprite.say("Listen...")
play_sound_until_done(meow) # Waits for sound to finish
sprite.say("Done!") # Only runs after sound ends
stop_all_sounds()
Stop all currently playing sounds.
stop_all_sounds()
Volume Control
Control the global volume of all sounds (0-100, like Scratch).
set_volume(value)
Set the volume (0-100).
set_volume(50) # 50% volume
set_volume(100) # Full volume
set_volume(0) # Muted
change_volume(amount)
Change the volume by an amount.
change_volume(10) # Volume up by 10
change_volume(-20) # Volume down by 20
get_volume()
Get the current volume level (0-100).
vol = get_volume()
sprite.say(f"Volume: {vol}%")
Sound Effects
Apply effects to sounds like pitch and stereo panning.
set_pitch_effect(value)
Set the pitch effect (like Scratch). Range is approximately -360 to 360.
0= normal pitch- Positive values = higher pitch (faster playback)
- Negative values = lower pitch (slower playback)
set_pitch_effect(60) # Higher pitch
set_pitch_effect(-60) # Lower pitch
set_pitch_effect(0) # Normal
change_pitch_effect(amount)
Change the pitch effect by an amount.
change_pitch_effect(10) # Increase pitch
change_pitch_effect(-20) # Decrease pitch
set_pan_effect(value)
Set the stereo pan (like Scratch’s “set pan left/right” effect).
-100= full left speaker0= center (both speakers)100= full right speaker
set_pan_effect(-100) # Full left
set_pan_effect(0) # Center
set_pan_effect(100) # Full right
change_pan_effect(amount)
Change the pan effect by an amount.
change_pan_effect(50) # Pan more to the right
clear_sound_effects()
Reset all sound effects (pitch and pan) to normal.
clear_sound_effects() # Reset to normal pitch and center pan
Example: Playing Sounds with Effects
stage = Stage()
cat = Sprite("cat")
stage.add_sprite(cat)
# Load sounds - each returns a Sound object
coin_sound = load_sound("sfx_coin_single1")
fanfare_sound = load_sound("sfx_sounds_fanfare1")
@on_start
def setup():
set_volume(70) # 70% volume
start_sound(fanfare_sound) # Play a fanfare
@on_key_press("space")
def coin():
cat.say("Coin!")
start_sound(coin_sound)
@on_key_press("up arrow")
def volume_up():
change_volume(10)
cat.say(f"Volume: {get_volume()}%")
@on_key_press("down arrow")
def volume_down():
change_volume(-10)
cat.say(f"Volume: {get_volume()}%")
@on_key_press("s")
def stop_sounds():
stop_all_sounds()
cat.say("Stopped!")
Asset Map
EktuPy includes an asset map that makes it easy to use sprites and sounds by name instead of remembering full paths.
How It Works
The asset map is a JSON file (asset_map.json) that maps asset names to their full paths. This is generated from the static/assets/sprites and static/assets/sounds directories.
When you use an asset name (without slashes), EktuPy automatically looks it up in the asset map and uses the full path.
Using Asset Names
Sprites:
# Instead of using the full path:
snake = Sprite("/static/assets/sprites/snake.svg")
# You can use the asset name:
snake = Sprite("snake")
Sounds:
# Load a sound by name - returns a Sound object
hit_sound = load_sound("sfx_sound_neutral1")
# Then use it to play the sound
start_sound(hit_sound)
Benefits
- Shorter code: No need to type long paths
- Editor validation: The editor shows a warning if you use a name that doesn’t exist
- Easier to remember: Use descriptive names instead of file paths
Helper Functions
get_available_sprites()
Get a list of all available sprite asset names.
sprites = get_available_sprites()
print(sprites) # ['snake', 'paddle', 'ball-solid', ...]
get_available_sounds()
Get a list of all available sound asset names.
sounds = get_available_sounds()
print(sounds) # ['sfx_sound_neutral1', 'sfx_sound_neutral2', ...]
get_available_backdrops()
Get a list of all available backdrop asset names.
backdrops = get_available_backdrops()
print(backdrops) # ['jungle', 'mountain-sunrise', 'paddy-field', 'race-track', 'sky-and-clouds']
Naming Conflicts
If two files have the same basename but different extensions (e.g., ball.svg and ball.png), they are differentiated by adding the extension to the name:
ball-svgforball.svgball-pngforball.png