EktuPy Examples
This page contains example programs demonstrating EktuPy features. Each example shows a different aspect of the API.
Hello World
The simplest EktuPy program - display a sprite with a speech bubble.
from ektupy import Stage, Sprite, on_start
stage = Stage()
snake = Sprite("snake")
stage.add_sprite(snake)
@on_start
def setup():
snake.go_to(0, 0)
snake.say("Hello! Use arrow keys to move me!", 3)
Key concepts: Stage(), Sprite(), @on_start, say()

Arrow Key Movement
Move a sprite around the stage using arrow keys.
from ektupy import Stage, Sprite, on_start, on_forever, key_pressed
stage = Stage()
snake = Sprite("snake")
stage.add_sprite(snake)
@on_start
def setup():
snake.go_to(0, 0)
snake.say("Hello! Use arrow keys to move me!", 3)
@on_forever
def game_loop():
if key_pressed("right arrow"):
snake.direction = 90
snake.move(5)
if key_pressed("left arrow"):
snake.direction = -90
snake.move(5)
if key_pressed("up arrow"):
snake.direction = 0
snake.move(5)
if key_pressed("down arrow"):
snake.direction = 180
snake.move(5)
Key concepts: @on_forever, key_pressed(), direction, move()

Bouncing Ball
A sprite that bounces around the stage continuously.
from ektupy import Stage, Sprite, on_start, on_forever
stage = Stage()
snake = Sprite("snake")
stage.add_sprite(snake)
@on_start
def setup():
snake.go_to(0, 0)
snake.direction = 45
snake.set_rotation_style("all around")
@on_forever
def game_loop():
snake.move(5)
snake.bounce_if_on_edge()
Key concepts: set_rotation_style(), bounce_if_on_edge()

Drawing with Pen
Use the pen to draw shapes as the sprite moves.
from ektupy import Stage, Sprite, on_start, on_forever, key_pressed
stage = Stage()
stage.set_background("#222222")
pen = Sprite("snake")
stage.add_sprite(pen)
@on_start
def setup():
pen.go_to(0, 0)
pen.set_pen_color("#00FF00")
pen.set_pen_size(3)
pen.pen_down()
@on_forever
def draw():
if key_pressed("right arrow"):
pen.direction = 90
pen.move(3)
if key_pressed("left arrow"):
pen.direction = -90
pen.move(3)
if key_pressed("up arrow"):
pen.direction = 0
pen.move(3)
if key_pressed("down arrow"):
pen.direction = 180
pen.move(3)
if key_pressed("c"):
pen.clear()
if key_pressed("space"):
pen.pen_up()
pen.go_to(0, 0)
pen.pen_down()
Key concepts: pen_down(), pen_up(), set_pen_color(), set_pen_size(), clear()

Sound Effects
Play sounds with volume and pitch control.
from ektupy import Stage, Sprite, on_start, on_key_press
from ektupy import load_sound, start_sound, stop_all_sounds
from ektupy import set_volume, change_volume, get_volume
from ektupy import set_pitch_effect, clear_sound_effects
stage = Stage()
stage.set_background("#2d3436")
snake = Sprite("snake")
stage.add_sprite(snake)
@on_start
def setup():
snake.go_to(0, 0)
snake.size = 100
# Load sounds using asset names
load_sound("sfx_coin_single1")
load_sound("sfx_movement_jump1")
load_sound("sfx_menu_select1")
# Set initial volume
set_volume(70)
snake.say("Press: C=coin J=jump\nUP/DOWN=volume")
@on_key_press("c")
def play_coin():
start_sound("sfx_coin_single1")
snake.say(f"Coin! Vol: {get_volume()}%")
@on_key_press("j")
def play_jump():
start_sound("sfx_movement_jump1")
snake.say(f"Jump! Vol: {get_volume()}%")
@on_key_press("up arrow")
def volume_up():
change_volume(10)
snake.say(f"Volume: {get_volume()}%")
@on_key_press("down arrow")
def volume_down():
change_volume(-10)
snake.say(f"Volume: {get_volume()}%")
@on_key_press("p")
def pitch_up():
set_pitch_effect(60)
snake.say("High pitch!")
@on_key_press("n")
def pitch_normal():
clear_sound_effects()
snake.say("Normal pitch")
@on_key_press("s")
def stop_sounds():
stop_all_sounds()
snake.say("Stopped!")
Key concepts: load_sound(), start_sound(), set_volume(), change_volume(), get_volume(), set_pitch_effect(), clear_sound_effects(), stop_all_sounds()

Costume Animation
Switch between costumes to create animation effects.
from ektupy import Stage, Sprite, on_start, on_forever
stage = Stage()
stage.set_background("#2d3436")
# Create a snake sprite - automatically loads all costumes
snake = Sprite("snake")
stage.add_sprite(snake)
frame_count = 0
@on_start
def setup():
snake.go_to(0, 0)
snake.size = 150
# Show available costumes
print("Available costumes:", snake.costumes)
snake.say("I can change colors!", 2)
@on_forever
def animate():
global frame_count
frame_count += 1
# Move in a circle
snake.turn_right(3)
snake.move(5)
# Change costume every 20 frames
if frame_count % 20 == 0:
snake.next_costume()
print(f"Now wearing: {snake.costume_name}")
Key concepts: costumes, next_costume(), costume_name, switch_costume()

Ghost Effect (Transparency)
Make sprites fade in and out using the ghost effect.
from ektupy import Stage, Sprite, on_start, on_forever, on_key_press
stage = Stage()
stage.set_background("#1a1a2e")
ghost = Sprite("snake")
stage.add_sprite(ghost)
fade_direction = 1 # 1 = fading out, -1 = fading in
ghost_value = 0
@on_start
def setup():
ghost.go_to(0, 0)
ghost.size = 150
ghost.say("I fade in and out!\nPress SPACE to reset", 3)
@on_forever
def animate():
global fade_direction, ghost_value
# Change ghost effect (transparency)
ghost_value += fade_direction * 2
# Reverse direction at limits
if ghost_value >= 80:
fade_direction = -1
elif ghost_value <= 0:
fade_direction = 1
ghost.set_ghost_effect(ghost_value)
# Move in a circle
ghost.turn_right(2)
ghost.move(3)
ghost.bounce_if_on_edge()
@on_key_press("space")
def reset():
ghost.set_ghost_effect(0)
ghost.clear_graphic_effects()
ghost.go_to(0, 0)
ghost.say("Reset!")
Key concepts: set_ghost_effect(), change_ghost_effect(), clear_graphic_effects()

Sprite Layers
Control which sprites appear in front of others.
from ektupy import Stage, Sprite, on_start, on_key_press, wait
stage = Stage()
stage.set_background("#87CEEB")
# Create three overlapping sprites
red = Sprite("snake")
green = Sprite("snake")
blue = Sprite("snake")
stage.add_sprite(red)
stage.add_sprite(green)
stage.add_sprite(blue)
@on_start
def setup():
# Position sprites overlapping
red.go_to(-50, 0)
red.size = 150
green.go_to(0, 0)
green.size = 150
blue.go_to(50, 0)
blue.size = 150
red.say("R=front")
green.say("G=front")
blue.say("B=front")
@on_key_press("r")
def red_front():
red.go_to_front_layer()
red.say("I'm in front!")
green.say("")
blue.say("")
@on_key_press("g")
def green_front():
green.go_to_front_layer()
green.say("I'm in front!")
red.say("")
blue.say("")
@on_key_press("b")
def blue_front():
blue.go_to_front_layer()
blue.say("I'm in front!")
red.say("")
green.say("")
@on_key_press("space")
def reset_order():
red.go_to_back_layer()
green.go_forward_layers(1)
blue.go_to_front_layer()
red.say("Back")
green.say("Middle")
blue.say("Front")
Key concepts: go_to_front_layer(), go_to_back_layer(), go_forward_layers(), go_backward_layers()

Stamping Patterns
Use stamp() to leave copies of the sprite on the stage.
from ektupy import Stage, Sprite, on_start, on_key_press
stage = Stage()
stage.set_background("#1a1a2e")
snake = Sprite("snake")
stage.add_sprite(snake)
@on_start
def setup():
snake.go_to(0, 0)
snake.size = 30
snake.say("Press S=spiral G=grid C=clear", 3)
@on_key_press("s")
def draw_spiral():
snake.go_to(0, 0)
snake.direction = 0
snake.size = 20
# Draw a spiral pattern using stamps
for i in range(36):
snake.stamp()
snake.move(10 + i * 2)
snake.turn_right(30)
snake.size = 20 + i
snake.say("Spiral complete!")
@on_key_press("c")
def clear_stamps():
snake.clear()
snake.go_to(0, 0)
snake.size = 30
snake.say("Cleared!")
@on_key_press("g")
def draw_grid():
snake.size = 20
# Draw a grid pattern
for row in range(-4, 5):
for col in range(-6, 7):
snake.go_to(col * 60, row * 60)
snake.stamp()
snake.go_to(0, 0)
snake.say("Grid complete!")
Key concepts: stamp(), clear()

Mouse Tracking
Follow the mouse and detect proximity.
from ektupy import Stage, Sprite, on_start, on_forever
from ektupy import mouse_x, mouse_y
stage = Stage()
stage.set_background("#2d5a27")
snake = Sprite("snake")
stage.add_sprite(snake)
@snake.on_start
def setup():
snake.go_to(0, 0)
snake.size = 80
@snake.on_forever
def track_mouse():
# Calculate distance to mouse
dist = snake.distance_to_mouse()
# Check if touching mouse pointer
if snake.touching_mouse():
snake.say("You caught me!")
elif dist < 80:
snake.say("Too close!")
elif dist < 150:
snake.say("Getting warmer...")
else:
snake.say(f"Distance: {int(dist)}")
# Slowly move toward mouse
snake.point_towards_mouse()
if dist > 10:
snake.move(2)
Key concepts: distance_to_mouse(), touching_mouse(), point_towards_mouse(), mouse_x(), mouse_y()
![]()
User Input (Ask and Answer)
Get text input from the user.
from ektupy import Stage, Sprite, on_start, on_key_press
from ektupy import ask, answer, wait
stage = Stage()
stage.set_background("#4a90d9")
snake = Sprite("snake")
stage.add_sprite(snake)
@snake.on_start
def greet():
snake.go_to(0, 100)
snake.size = 100
# Ask for the user's name
name = ask("What's your name?")
# Use the answer
snake.say(f"Hello, {name}! Nice to meet you!")
wait(2)
# Ask another question
color = ask("What's your favorite color?")
snake.say(f"{color} is a great color!")
wait(2)
snake.say("Press SPACE to ask again!")
@snake.on_key_press("space")
def ask_again():
response = ask("Tell me something interesting:")
snake.say(f'You said: "{response}"')
Key concepts: ask(), answer() - the input box appears at the bottom of the stage

Timer and Clock
Use sensing functions for time.
from ektupy import Stage, Sprite, on_start, on_forever
from ektupy import timer, reset_timer
from ektupy import current_hour, current_minute, current_second, current_day_of_week
stage = Stage()
stage.set_background("#1a1a2e")
clock = Sprite("snake")
stage.add_sprite(clock)
days = ["", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
@clock.on_start
def setup():
clock.go_to(0, 100)
clock.size = 100
reset_timer()
@clock.on_forever
def update_clock():
h = current_hour()
m = current_minute()
s = current_second()
day = days[current_day_of_week()]
# Format time with leading zeros
time_str = f"{h:02d}:{m:02d}:{s:02d}"
elapsed = int(timer())
clock.say(f"{day}\n{time_str}\nRunning: {elapsed}s")
Key concepts: timer(), reset_timer(), current_hour(), current_minute(), current_second(), current_day_of_week()

Two Sprites with Independent Controls
Each sprite has its own scripts and responds to different keys.
from ektupy import Stage, Sprite, wait, broadcast
stage = Stage()
stage.set_background("#87CEEB")
cat = Sprite("cat")
dog = Sprite("dog")
stage.add_sprite(cat)
stage.add_sprite(dog)
# ============================================
# CAT'S SCRIPTS - Use arrow keys to move
# ============================================
@cat.on_start
def cat_setup():
cat.go_to(-100, 0)
cat.say("I'm the cat! Use arrow keys to move me.")
wait(3)
cat.say("")
@cat.on_key_press("up arrow")
def cat_up():
cat.change_y(10)
@cat.on_key_press("down arrow")
def cat_down():
cat.change_y(-10)
@cat.on_key_press("left arrow")
def cat_left():
cat.change_x(-10)
@cat.on_key_press("right arrow")
def cat_right():
cat.change_x(10)
@cat.on_message("woof")
def cat_hears_woof():
cat.say("Meow back!")
wait(1)
cat.say("")
# ============================================
# DOG'S SCRIPTS - Use WASD keys to move
# ============================================
@dog.on_start
def dog_setup():
dog.go_to(100, 0)
dog.say("I'm the dog! Use WASD to move me.")
wait(3)
dog.say("")
@dog.on_key_press("w")
def dog_up():
dog.change_y(10)
@dog.on_key_press("s")
def dog_down():
dog.change_y(-10)
@dog.on_key_press("a")
def dog_left():
dog.change_x(-10)
@dog.on_key_press("d")
def dog_right():
dog.change_x(10)
@dog.on_key_press("space")
def dog_bark():
dog.say("Woof!")
broadcast("woof")
wait(1)
dog.say("")
# ============================================
# COLLISION DETECTION
# ============================================
@cat.on_forever
def check_collision():
if cat.touching(dog):
cat.say("Hey!")
dog.say("Hi friend!")
Key concepts: Per-sprite decorators (@sprite.on_start, @sprite.on_key_press, @sprite.on_message), touching(), broadcast()
![]()
Cloning
Create multiple copies of a sprite at runtime.
from ektupy import Stage, Sprite, on_start, on_key_press
import random
stage = Stage()
stage.set_background("#1a1a2e")
star = Sprite("snake")
stage.add_sprite(star)
@star.on_start
def star_setup():
star.hide()
star.size = 30
def on_clone_created():
star.show()
star.go_to_random_position()
star.set_ghost_effect(random.randint(0, 50))
star.on_clone_start(on_clone_created)
@on_start
def setup():
print("Press SPACE to create stars!")
@on_key_press("space")
def create_star():
star.clone()
print("Created a star!")
Key concepts: clone(), on_clone_start(), is_clone, delete_clone(), go_to_random_position()

Click to Move
Click anywhere on the stage to move the sprite there smoothly.
from ektupy import Stage, Sprite, on_start, on_mouse_click
stage = Stage()
sprite = Sprite("snake")
stage.add_sprite(sprite)
@on_start
def setup():
sprite.go_to(0, 0)
sprite.say("Click anywhere!")
@on_mouse_click
def move_to_click(x, y):
sprite.glide_to(x, y, 0.5)
sprite.say(f"({int(x)}, {int(y)})")
Key concepts: @on_mouse_click, glide_to()

Broadcasting Messages
Use broadcasts to coordinate between sprites.
from ektupy import Stage, Sprite, on_start, on_key_press, on_message, broadcast, wait
stage = Stage()
button = Sprite("snake")
responder = Sprite("cat")
stage.add_sprite(button)
stage.add_sprite(responder)
@button.on_start
def button_setup():
button.go_to(-100, 0)
button.say("Press SPACE!")
@responder.on_start
def responder_setup():
responder.go_to(100, 0)
@on_key_press("space")
def send_message():
button.say("Sending...")
broadcast("hello")
wait(0.5)
button.say("Press SPACE!")
@responder.on_message("hello")
def receive_message():
responder.say("Got it!")
responder.change_y(20)
wait(0.5)
responder.change_y(-20)
responder.say("")
Key concepts: broadcast(), @on_message, broadcast_and_wait()

Background Images
Use backdrop images for your stage.
from ektupy import Stage, Sprite, on_start, on_forever, key_pressed
stage = Stage()
stage.set_background_image("mountain-sunrise")
snake = Sprite("snake")
stage.add_sprite(snake)
# Available backdrops: mountain-sunrise, jungle, paddy-field, race-track, sky-and-clouds
backdrops = ["mountain-sunrise", "jungle", "paddy-field", "race-track", "sky-and-clouds"]
current_backdrop = 0
@on_start
def setup():
snake.go_to(0, -200)
snake.say("Press SPACE to change backdrop!", 3)
@on_forever
def game_loop():
global current_backdrop
# Move with arrow keys
if key_pressed("right arrow"):
snake.direction = 90
snake.move(5)
if key_pressed("left arrow"):
snake.direction = -90
snake.move(5)
if key_pressed("up arrow"):
snake.direction = 0
snake.move(5)
if key_pressed("down arrow"):
snake.direction = 180
snake.move(5)
# Change backdrop with space
if key_pressed("space"):
current_backdrop = (current_backdrop + 1) % len(backdrops)
stage.set_background_image(backdrops[current_backdrop])
snake.say(backdrops[current_backdrop], 1)
Key concepts: set_background_image(), available backdrops: jungle, mountain-sunrise, paddy-field, race-track, sky-and-clouds
