or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

effects-and-animation.mdindex.mdparticles-and-sprites.mdrenderers.mdscreen-and-display.mdwidgets-and-ui.md
tile.json

particles-and-sprites.mddocs/

Particles and Sprites

Advanced particle system for creating fireworks, explosions, rain, and other dynamic effects, combined with sprite animation support for character-based animations and custom drawable objects. The particle system provides realistic physics simulation while sprites enable complex animated sequences.

Capabilities

Particle System Base Classes

The foundation classes for creating particle-based effects with physics simulation and lifecycle management.

class Particle:
    """Individual particle with physics properties"""
    
    def __init__(self, x, y, dx, dy, char, colour, life_time, bg=0):
        """
        Initialize particle with position, velocity, and appearance.
        
        Parameters:
        - x (float): Initial X position
        - y (float): Initial Y position
        - dx (float): X velocity
        - dy (float): Y velocity
        - char (str): Character to display for particle
        - colour (int): Particle color
        - life_time (int): Frames particle will live
        - bg (int): Background color
        """
        
    def update(self):
        """Update particle position and physics"""
        
    @property
    def is_alive(self):
        """Whether particle is still alive"""

class ParticleEmitter:
    """Base class for particle emission sources"""
    
    def __init__(self, screen, x, y, max_particles=100):
        """
        Initialize particle emitter.
        
        Parameters:
        - screen (Screen): Target screen for rendering
        - x (int): Emitter X position
        - y (int): Emitter Y position
        - max_particles (int): Maximum particles to emit
        """
        
    def update(self, frame_no):
        """
        Update emitter and emit new particles.
        
        Parameters:
        - frame_no (int): Current animation frame
        
        Returns:
        list: List of new particles created this frame
        """

class ParticleEffect(Effect):
    """Base class for particle-based effects"""
    
    def __init__(self, screen, x, y, life_time, start_frame=0, stop_frame=0):
        """
        Initialize particle effect.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Effect center X position
        - y (int): Effect center Y position
        - life_time (int): Effect duration in frames
        - start_frame (int): Frame to start effect
        - stop_frame (int): Frame to stop effect
        """

Particle Emitters

Specialized emitters for different types of particle behaviors and visual effects.

class Rocket(ParticleEmitter):
    """Rocket trail particle emitter"""
    
    def __init__(self, screen, x, y, dx, dy, life_time, colour):
        """
        Initialize rocket emitter.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Starting X position
        - y (int): Starting Y position
        - dx (float): X direction/velocity
        - dy (float): Y direction/velocity
        - life_time (int): Rocket trail duration
        - colour (int): Rocket color
        """

class RingExplosion(ParticleEmitter):
    """Ring explosion particle emitter"""
    
    def __init__(self, screen, x, y, life_time, colour):
        """
        Initialize ring explosion emitter.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Explosion center X
        - y (int): Explosion center Y
        - life_time (int): Explosion duration
        - colour (int): Explosion color
        """

class SerpentExplosion(ParticleEmitter):
    """Serpent-style explosion particle emitter"""
    
    def __init__(self, screen, x, y, life_time, colour):
        """
        Initialize serpent explosion emitter.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Explosion center X
        - y (int): Explosion center Y
        - life_time (int): Explosion duration
        - colour (int): Explosion color
        """

class StarExplosion(ParticleEmitter):
    """Star-shaped explosion particle emitter"""
    
    def __init__(self, screen, x, y, life_time, colour):
        """
        Initialize star explosion emitter.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Explosion center X
        - y (int): Explosion center Y
        - life_time (int): Explosion duration
        - colour (int): Explosion color
        """

class StarTrail(ParticleEmitter):
    """Star trail particle emitter"""
    
    def __init__(self, screen, x, y, life_time, colour):
        """
        Initialize star trail emitter.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Trail start X
        - y (int): Trail start Y
        - life_time (int): Trail duration
        - colour (int): Trail color
        """

class PalmExplosion(ParticleEmitter):
    """Palm tree explosion particle emitter"""
    
    def __init__(self, screen, x, y, life_time, colour):
        """
        Initialize palm explosion emitter.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Explosion center X
        - y (int): Explosion center Y
        - life_time (int): Explosion duration
        - colour (int): Explosion color
        """

class ExplosionFlames(ParticleEmitter):
    """Explosion flames particle emitter"""
    
    def __init__(self, screen, x, y, life_time, colour):
        """
        Initialize explosion flames emitter.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Flames center X
        - y (int): Flames center Y
        - life_time (int): Flames duration
        - colour (int): Flames color
        """

Environmental Emitters

Emitters for environmental effects like rain, drops, and weather.

class DropEmitter(ParticleEmitter):
    """Water drop particle emitter"""
    
    def __init__(self, screen, x, y, rate, colour):
        """
        Initialize drop emitter.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Drop source X
        - y (int): Drop source Y
        - rate (float): Drop emission rate
        - colour (int): Drop color
        """

class ShotEmitter(ParticleEmitter):
    """Shot/bullet particle emitter"""
    
    def __init__(self, screen, x, y, dx, dy, colour, life_time):
        """
        Initialize shot emitter.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Shot origin X
        - y (int): Shot origin Y
        - dx (float): Shot X velocity
        - dy (float): Shot Y velocity
        - colour (int): Shot color
        - life_time (int): Shot duration
        """

class RainSource(ParticleEmitter):
    """Rain source particle emitter"""
    
    def __init__(self, screen, width, intensity, colour):
        """
        Initialize rain source emitter.
        
        Parameters:
        - screen (Screen): Target screen
        - width (int): Rain area width
        - intensity (float): Rain intensity/rate
        - colour (int): Rain color
        """

class Splash(ParticleEmitter):
    """Water splash particle emitter"""
    
    def __init__(self, screen, x, y, life_time, colour):
        """
        Initialize splash emitter.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Splash center X
        - y (int): Splash center Y
        - life_time (int): Splash duration
        - colour (int): Splash color
        """

Firework Effects

Complete firework effects combining multiple emitters for realistic pyrotechnic displays.

class StarFirework(ParticleEffect):
    """Star-shaped firework effect"""
    
    def __init__(self, screen, x, y, life_time, firework_colour=7, trail_colour=None, start_frame=0):
        """
        Initialize star firework effect.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Firework X position
        - y (int): Firework Y position
        - life_time (int): Firework duration
        - firework_colour (int): Main firework color
        - trail_colour (int): Trail color (None = same as firework)
        - start_frame (int): Frame to start firework
        """

class RingFirework(ParticleEffect):
    """Ring-shaped firework effect"""
    
    def __init__(self, screen, x, y, life_time, firework_colour=7, trail_colour=None, start_frame=0):
        """
        Initialize ring firework effect.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Firework X position
        - y (int): Firework Y position
        - life_time (int): Firework duration
        - firework_colour (int): Main firework color
        - trail_colour (int): Trail color (None = same as firework)
        - start_frame (int): Frame to start firework
        """

class SerpentFirework(ParticleEffect):
    """Serpent-style firework effect"""
    
    def __init__(self, screen, x, y, life_time, firework_colour=7, trail_colour=None, start_frame=0):
        """
        Initialize serpent firework effect.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Firework X position
        - y (int): Firework Y position
        - life_time (int): Firework duration
        - firework_colour (int): Main firework color
        - trail_colour (int): Trail color (None = same as firework)
        - start_frame (int): Frame to start firework
        """

class PalmFirework(ParticleEffect):
    """Palm tree firework effect"""
    
    def __init__(self, screen, x, y, life_time, firework_colour=7, trail_colour=None, start_frame=0):
        """
        Initialize palm firework effect.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Firework X position
        - y (int): Firework Y position
        - life_time (int): Firework duration
        - firework_colour (int): Main firework color
        - trail_colour (int): Trail color (None = same as firework)
        - start_frame (int): Frame to start firework
        """

class Explosion(ParticleEffect):
    """Generic explosion effect"""
    
    def __init__(self, screen, x, y, life_time, start_frame=0):
        """
        Initialize explosion effect.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Explosion center X
        - y (int): Explosion center Y
        - life_time (int): Explosion duration
        - start_frame (int): Frame to start explosion
        """

Environmental Effects

Large-scale environmental effects using particle systems.

class DropScreen(ParticleEffect):
    """Full-screen drop effect"""
    
    def __init__(self, screen, life_time, start_frame=0):
        """
        Initialize drop screen effect.
        
        Parameters:
        - screen (Screen): Target screen
        - life_time (int): Effect duration
        - start_frame (int): Frame to start effect
        """

class ShootScreen(ParticleEffect):
    """Full-screen shooting effect"""
    
    def __init__(self, screen, life_time, start_frame=0):
        """
        Initialize shoot screen effect.
        
        Parameters:
        - screen (Screen): Target screen
        - life_time (int): Effect duration
        - start_frame (int): Frame to start effect
        """

class Rain(ParticleEffect):
    """Rain weather effect"""
    
    def __init__(self, screen, life_time, start_frame=0):
        """
        Initialize rain effect.
        
        Parameters:
        - screen (Screen): Target screen
        - life_time (int): Rain duration
        - start_frame (int): Frame to start rain
        """

Sprite System

Character-based animation system for complex moving objects and sequences.

class Sprite(Effect):
    """Moving sprite animation effect"""
    
    def __init__(self, screen, renderer_dict, path, colour=7, attr=2, bg=0, clear=True, start_frame=0, stop_frame=0):
        """
        Initialize sprite animation.
        
        Parameters:
        - screen (Screen): Target screen
        - renderer_dict (dict): Dictionary mapping animation states to renderers
        - path (Path): Animation path for sprite movement
        - colour (int): Sprite color
        - attr (int): Text attributes
        - bg (int): Background color
        - clear (bool): Whether to clear sprite trail
        - start_frame (int): Frame to start animation
        - stop_frame (int): Frame to stop animation
        """
        
    def overlaps(self, other_sprite, use_new_pos=False):
        """
        Check if sprite overlaps with another sprite.
        
        Parameters:
        - other_sprite (Sprite): Other sprite to check collision with
        - use_new_pos (bool): Whether to use new position for check
        
        Returns:
        bool: True if sprites overlap
        """
        
    @property
    def x(self):
        """Current sprite X position"""
        
    @property
    def y(self):
        """Current sprite Y position"""

class Sam(Sprite):
    """Sam character sprite with built-in animations"""
    
    def __init__(self, screen, path, start_frame=0, stop_frame=0):
        """
        Initialize Sam sprite.
        
        Parameters:
        - screen (Screen): Target screen
        - path (Path): Movement path for Sam
        - start_frame (int): Frame to start animation
        - stop_frame (int): Frame to stop animation
        """

class Arrow(Sprite):
    """Arrow sprite for projectiles and indicators"""
    
    def __init__(self, screen, path, colour=7, start_frame=0, stop_frame=0):
        """
        Initialize arrow sprite.
        
        Parameters:
        - screen (Screen): Target screen
        - path (Path): Movement path for arrow
        - colour (int): Arrow color
        - start_frame (int): Frame to start animation
        - stop_frame (int): Frame to stop animation
        """

class Plot(Sprite):
    """Plot/graph sprite for data visualization"""
    
    def __init__(self, screen, path, colour=7, start_frame=0, stop_frame=0):
        """
        Initialize plot sprite.
        
        Parameters:
        - screen (Screen): Target screen
        - path (Path): Movement path for plot
        - colour (int): Plot color
        - start_frame (int): Frame to start animation
        - stop_frame (int): Frame to stop animation
        """

class Arrow(Sprite):
    """Arrow sprite for projectiles and indicators"""
    
    def __init__(self, screen, path, colour=7, start_frame=0, stop_frame=0):
        """
        Initialize arrow sprite.
        
        Parameters:
        - screen (Screen): Target screen
        - path (Path): Movement path for arrow
        - colour (int): Arrow color
        - start_frame (int): Frame to start animation
        - stop_frame (int): Frame to stop animation
        """

Animation Paths

Path system for controlling sprite movement and animation trajectories.

class Path:
    """Static animation path for sprite movement"""
    
    def __init__(self, screen, x, y, path):
        """
        Initialize static path.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Starting X position
        - y (int): Starting Y position
        - path (str): Path string defining movement
        """
        
    def next_pos(self):
        """
        Get next position on path.
        
        Returns:
        tuple: (x, y, finished) position and completion status
        """

class DynamicPath:
    """Abstract base class for dynamic animation paths"""
    
    def __init__(self, screen, x, y):
        """
        Initialize dynamic path.
        
        Parameters:
        - screen (Screen): Target screen
        - x (int): Starting X position
        - y (int): Starting Y position
        """
        
    def process_event(self, event):
        """
        Process input event for path modification.
        
        Parameters:
        - event (Event): Input event to process
        """
        
    def next_pos(self):
        """
        Get next position on dynamic path.
        
        Returns:
        tuple: (x, y, finished) position and completion status
        """

Usage Examples

Fireworks Display

from asciimatics.screen import ManagedScreen
from asciimatics.scene import Scene
from asciimatics.particles import StarFirework, RingFirework, PalmFirework
from asciimatics.effects import Stars
import random

def fireworks_demo(screen):
    effects = [
        Stars(screen, 200),  # Background stars
    ]
    
    # Add random fireworks
    for i in range(10):
        x = random.randint(10, screen.width - 10)
        y = random.randint(5, screen.height // 2)
        start_time = random.randint(0, 300)
        firework_type = random.choice([StarFirework, RingFirework, PalmFirework])
        color = random.randint(1, 7)
        
        effects.append(
            firework_type(screen, x, y, 100, 
                         firework_colour=color, 
                         start_frame=start_time)
        )
    
    screen.play([Scene(effects, 500)])

ManagedScreen(fireworks_demo).run()

Rain Effect

from asciimatics.particles import Rain
from asciimatics.effects import Print
from asciimatics.renderers import FigletText

def rain_demo(screen):
    effects = [
        Rain(screen, -1),  # Infinite rain
        Print(screen,
              FigletText("RAINY DAY", font='small'),
              screen.height // 2,
              colour=Screen.COLOUR_BLUE)
    ]
    
    screen.play([Scene(effects, -1)])

ManagedScreen(rain_demo).run()

Sprite Animation

from asciimatics.sprites import Sam
from asciimatics.paths import Path
from asciimatics.effects import Stars

def sprite_demo(screen):
    # Create path for Sam to follow
    path_string = f"M{screen.width//4},{screen.height//2} L{screen.width*3//4},{screen.height//2}"
    path = Path(screen, screen.width//4, screen.height//2, path_string)
    
    effects = [
        Stars(screen, 100),  # Background
        Sam(screen, path)    # Sam sprite following path
    ]
    
    screen.play([Scene(effects, 500)])

ManagedScreen(sprite_demo).run()

Custom Particle Effect

from asciimatics.particles import ParticleEffect, ParticleEmitter, Particle
import random

class SnowFlakeEmitter(ParticleEmitter):
    """Custom snowflake particle emitter"""
    
    def update(self, frame_no):
        particles = []
        
        # Emit snowflakes from top of screen
        if frame_no % 3 == 0:  # Every 3 frames
            x = random.randint(0, self._screen.width - 1)
            particle = Particle(
                x=x, y=0,
                dx=random.uniform(-0.5, 0.5),  # Slight horizontal drift
                dy=random.uniform(0.2, 0.8),   # Downward movement
                char="*",
                colour=Screen.COLOUR_WHITE,
                life_time=self._screen.height * 2  # Live long enough to cross screen
            )
            particles.append(particle)
            
        return particles

class CustomSnow(ParticleEffect):
    """Custom snow effect using snowflake emitter"""
    
    def __init__(self, screen, life_time, start_frame=0):
        super().__init__(screen, 0, 0, life_time, start_frame)
        self._emitter = SnowFlakeEmitter(screen, 0, 0)
        self._particles = []
        
    def update(self, frame_no):
        # Add new particles
        new_particles = self._emitter.update(frame_no)
        self._particles.extend(new_particles)
        
        # Update existing particles
        active_particles = []
        for particle in self._particles:
            particle.update()
            if particle.is_alive and 0 <= particle.y < self._screen.height:
                active_particles.append(particle)
                self._screen.print_at(
                    particle.char,
                    int(particle.x),
                    int(particle.y),
                    particle.colour
                )
        self._particles = active_particles
        
        return True

def custom_snow_demo(screen):
    effects = [
        CustomSnow(screen, -1)  # Infinite snow
    ]
    
    screen.play([Scene(effects, -1)])

ManagedScreen(custom_snow_demo).run()

Collision Detection with Sprites

from asciimatics.sprites import Sam, Arrow
from asciimatics.paths import Path

def collision_demo(screen):
    # Create paths
    sam_path = Path(screen, 10, screen.height//2, 
                   f"L{screen.width-20},{screen.height//2}")
    arrow_path = Path(screen, screen.width-10, screen.height//2-5,
                     f"L10,{screen.height//2-5}")
    
    # Create sprites
    sam = Sam(screen, sam_path)
    arrow = Arrow(screen, arrow_path, colour=Screen.COLOUR_RED)
    
    class CollisionChecker(Effect):
        def __init__(self, sprite1, sprite2):
            super().__init__(screen)
            self._sprite1 = sprite1
            self._sprite2 = sprite2
            
        def update(self, frame_no):
            if self._sprite1.overlaps(self._sprite2):
                self._screen.print_at("COLLISION!", 
                                    screen.width//2-5, 
                                    screen.height//2+5,
                                    Screen.COLOUR_YELLOW,
                                    Screen.A_BOLD)
            return True
    
    effects = [
        sam,
        arrow,
        CollisionChecker(sam, arrow)
    ]
    
    screen.play([Scene(effects, 400)])

ManagedScreen(collision_demo).run()