Skip to main content

A simple terminal animation library

Project description

Animpy

PyPI - Version Downloads GitHub License

Animpy is a Python library for building lightweight terminal-based animations, visual effects, mini-games, and interactive apps. It gives you a simple API for placing text objects on a scene, moving them, coloring them, applying physics, reacting to input, playing sound, and even following a moving target with a camera-style offset.

It is built for developers who want to create animated terminal experiences without needing a full game engine or a graphical UI framework.

What Animpy can do

  • Create and animate text objects in the terminal
  • Draw shapes such as rectangles, circles, polygons, lines, hearts, triangles, ellipses, squares, and donuts
  • Create particle bursts, trails, and explosions
  • Apply built-in visual effects such as shaking, gravity, decay, fading, interpolation, pulsing, and typing effects
  • Build scenes with layered objects, background colors, offsets, and camera-style views
  • Add physics behaviors such as gravity, friction, bounce, angular motion, and force pushes
  • Handle keyboard and mouse input for interactive demos and games
  • Play audio clips with basic playback controls
  • Format terminal output with color, panels, centering helpers, and ANSI utilities

Installation

pip install animpy

Animpy depends on the following packages:

  • pygame-ce
  • keyboard
  • mouse
  • rich

Quick start

import animpy

scene = animpy.Scene()
text = animpy.Text("Hello!", 10, 5, r=255, g=100, b=50)
scene.add(text)
scene.render()

A more animated example:

import animpy
import time

scene = animpy.Scene()
text = animpy.Text("Hello", 0, 0, r=0, g=255, b=255)
scene.add(text)

for _ in range(20):
    text.moveX(1)
    scene.render()
    time.sleep(0.05)

Core concepts

1. Scenes

A Scene is the container that holds objects to be rendered to the terminal. It manages the draw order, background color, offsets, and optional camera logic.

scene = animpy.Scene()
scene.set_bg_rgb(0, 0, 30)

2. Text objects

Text is the basic object that can be placed on the screen and moved around. Text can also be created from a list of frames, which allows simple frame-based animation.

text = animpy.Text("Hello", 5, 3)
text.moveX(4)
text.moveY(2)
text.set_color(255, 0, 0)

3. Effects and motion

EffectText adds common visual effects and movement helpers on top of Text.

fx = animpy.EffectText("Bounce", 10, 2)
fx.shaking_text(intensity=2)
fx.gravity_text(floor=10, gravity=0.5)

4. Groups

A Group lets you manage many objects as one unit. Position and color changes can be applied to the entire group.

group = animpy.Group()
group.add(animpy.Text("A", 1, 1), animpy.Text("B", 4, 1))
group.position(2, 0)

5. Camera

A Camera provides a simple view transform for a scene. You can point it at a target object or keep a custom offset.

scene = animpy.Scene()
player = animpy.Text("P", 10, 5)
scene.add(player)

camera = animpy.Camera((0, 0), None)
camera.follow(player)
scene.camera = camera
scene.render()

Feature reference

Text

Text is the base class for terminal objects.

text = animpy.Text("Hello", 2, 2, r=255, g=255, b=255)

Common methods:

  • change_frame() — advance to the next frame if the text was created from a list
  • set_frame(index) — switch to a specific frame
  • set_text(text) — replace the text content or frame list
  • set_position(x, y) — directly set the position
  • move_to(x, y) — alias for set_position
  • set_color(r, g, b) — update the color using RGB values
  • change_rgb_values(r, g, b) — same as set_color
  • moveX(dx) — move horizontally
  • moveY(dy) — move vertically
  • slide_to_pos(new_pos, speed=1) — move smoothly toward a coordinate-like object
  • centerX() — center the text horizontally
  • centerY() — center the text vertically
  • collides_with(other) — test for bounding-box overlap
  • on_collide_callback(other, callback) — run a callback when collision occurs
  • type_out(text, speed=0.05, scene=None) — print text gradually, optionally rendering after each character
  • fall(velocity, floor) — move the object downward until a floor is reached

Useful properties:

  • width — number of characters in the current frame
  • height — number of lines in the current frame
  • current_frame — current frame index

EffectText

EffectText extends Text with reusable animation effects and velocity support.

fx = animpy.EffectText("Shaky", 5, 5)
fx.shaking_text(intensity=2)
fx.gravity_text(floor=10, gravity=0.5)
fx.pulse_text(time=1.0, pulse_rate=0.5)

Available methods:

  • gravity_text(floor=20, gravity=0.5) — apply gravity and clamp to a floor
  • shaking_text(intensity=1) — jitter position randomly
  • decaying_text(time, decay_rate=0.1) — shorten the text over time
  • fade_out_text(time, fade_rate=0.1) — fade the object toward black
  • lerp_text(target_x, target_y, t) — interpolate smoothly to a target position
  • pulse_text(time, pulse_rate=0.5) — change brightness over time
  • set_velocity(vx, vy) — set motion in X/Y
  • reset_velocity() — clear velocity values
  • apply_force(fx, fy) — add to the current velocity
  • fade_in_text(time, fade_rate=0.1) — fade in over time

Shapes

Shapes return multi-line strings that can be used as text content.

rect = animpy.Shapes.rectangle(8, 4, "#")
circle = animpy.Shapes.circle(4, "*")
line = animpy.Shapes.line(0, 0, 10, 4, "-")
heart = animpy.Shapes.heart(5, "♥")
triangle = animpy.Shapes.triangle(0, 0, 6, 0, 3, 5, "^")
ellipse = animpy.Shapes.ellipse(6, 3, 4, 2, "o")
square = animpy.Shapes.square(5, "#")
donut = animpy.Shapes.donut(5, 2, "#")

Supported builders:

  • rectangle(width, height, char)
  • circle(radius, char)
  • polygon(points, char)
  • line(x1, y1, x2, y2, char)
  • triangle(x1, y1, x2, y2, x3, y3, char)
  • ellipse(center_x, center_y, radius_x, radius_y, char)
  • heart(size, char)
  • square(size, char)
  • donut(outer_radius, inner_radius, char)

Group

A Group collects multiple objects so they can be moved or recolored together.

group = animpy.Group()
text1 = animpy.Text("A", 0, 0)
text2 = animpy.Text("B", 2, 0)
group.add(text1, text2)

group.position(3, 1)
group.change_rgb_values(0, 255, 0)

Available methods:

  • add(*items) — add one or more objects
  • remove(*items) — remove one or more objects
  • clear() — remove all items
  • contains(item) — check if an item exists in the group
  • find_by_color(r, g, b) — return matching items by color
  • position(newx, newy) — shift every item by an offset
  • change_rgb_values(r, g, b) — recolor every item
  • change_rgb_values_one(item, r, g, b) — recolor a single item

Coords, Keyframe, and KeyChains

These helpers support path-based movement.

from animpy import Coords, Keyframe, KeyChains

start = Coords(0, 0)
mid = Coords(10, 3)
end = Coords(15, 8)

path = KeyChains(Keyframe(start), Keyframe(mid), Keyframe(end))
path.follow_path(text, speed=1)
  • Coords(x, y) — simple coordinate container
  • distance_to(other) — calculate Euclidean distance
  • offset(dx, dy) — return a new offset coordinate
  • Keyframe(pos) — stores a target position
  • set_pos(pos) — update keyframe position
  • distance_to(other) — measure the distance to another keyframe or coordinate
  • KeyChains(*keyframes) — store a list of keyframes
  • append(keyframe) — add a keyframe
  • clear() — remove all keyframes
  • reverse_path() — reverse the path order
  • is_complete — becomes True once the path has no more keyframes
  • follow_path(obj, speed=1) — moves an object toward the current keyframe

Scene

A Scene handles rendering and object management.

scene = animpy.Scene()
scene.add(text1, text2)
scene.remove(text2)
scene.render()

Useful methods:

  • add(*items) — add objects to the scene
  • remove(*items) — remove objects from the scene
  • render() — draw the current frame to the terminal
  • update(delta_time) — update particles and remove expired items
  • set_bg_rgb(r, g, b) — set a background color
  • shake(intensity=1) — apply a random shaking offset
  • clear() — clear the terminal display
  • clear_items() — remove every object from the scene
  • count_items() — return the number of scene items
  • find_items_at(x, y) — return the objects sitting at a coordinate

Scene properties:

  • dt — elapsed time since the last frame
  • offset_x, offset_y — manual rendering offsets
  • camera — optional Camera attached to the scene

Camera

The Camera helper lets a scene render from a different view.

camera = animpy.Camera((0, 0), None)
camera.follow(player)
scene.camera = camera
scene.render()

Available methods:

  • move(new_position) — set the camera position directly
  • look_at(new_target) — point the camera at a new target
  • follow(target_object) — track an object by reference
  • get_view_matrix() — return the current view position as a tuple

PhysicsScene

PhysicsScene adds simple physical motion helpers to a scene.

scene = animpy.PhysicsScene()
ball = animpy.EffectText("O", 2, 2)
scene.add(ball)

scene.apply_gravity(ball)
scene.apply_friction(ball, friction=0.1)
scene.bounce(ball, bounce_factor=0.7)
scene.apply_physics(ball)
scene.angular_motion(ball, angle=45, speed=2.0)
scene.push(ball, force_x=0.5, force_y=-0.2)

Available methods:

  • apply_gravity(obj) — move an object downward toward the floor
  • apply_friction(obj, friction=0.1) — reduce velocity over time
  • bounce(obj, bounce_factor=0.5) — reverse vertical motion when hitting the floor
  • apply_physics(obj) — combine gravity, friction, and bounce
  • angular_motion(obj, angle, speed) — set an angled velocity
  • push(obj, force_x, force_y) — add force in X/Y directions

InteractiveScene

InteractiveScene makes it possible to react to keyboard and mouse input.

scene = animpy.InteractiveScene()
player = animpy.Text("P", 10, 10)
scene.add(player)

while True:
    if scene.key_pressed("w"):
        player.moveY(-1)
    if scene.key_pressed("s"):
        player.moveY(1)
    if scene.key_pressed("esc"):
        break
    scene.render()

Available methods:

  • key_pressed(key) — check whether a key is held down
  • key_released(key) — check whether a key has been released
  • on_key_press_callback(key, callback) — run a callback when a key is pressed
  • on_key_release_callback(key, callback) — run a callback when a key is released
  • mouse_pressed(button="left") — check whether a mouse button is held down
  • mouse_position() — return the current mouse position
  • on_mouse_press_callback(button, callback) — run a callback when a mouse button is pressed
  • mouse_release(button, callback) — run a callback when a button is released
  • mouse_release_callback(button, callback) — alias for the release callback helper
  • quick_exit(key="esc") — exit immediately when a key is pressed
  • quick_exit_callback(key, callback) — run a callback when a key is pressed
  • limit_to_bounds(obj) — keep an object inside the terminal area
  • limit_group_to_bounds(group) — keep every object in a group inside the terminal area

Particles

Particles are useful for trails, explosions, smoke, sparks, and other visual effects.

particle = animpy.Particle("*", 10, 5, r=255, g=150, b=50, lifetime=2.0)
particle.burst(scene, count=20, speed=1.5)

Available methods:

  • update(delta_time) — advance the particle in time
  • emit(scene) — add a single particle to the scene
  • burst(scene, count=10, speed=1.0) — create many particles with random velocities
  • change_rgb_values(r, g, b) — change the particle color
  • set_velocity(vx, vy) — set particle velocity
  • apply_force(fx, fy) — add velocity changes
  • set_color(r, g, b) — alias for setting color
  • reset(x, y, lifetime=None) — reset particle position and age
  • is_alive() — check whether the particle is still alive
  • update_all(delta_time) — update all particle children created by the parent
  • is_dead() — check whether all tracked particles are dead

There are also built-in particle presets:

  • Presets.create_explosion(x, y, count=20, speed=1.0, lifetime=1.0)
  • Presets.create_smoke(x, y, count=10, speed=0.5, lifetime=2.0)
  • Presets.create_firework(x, y, count=30, speed=2.0, lifetime=1.5)

Audio

Audio support is built on pygame and can be used to add music or effects.

audio = animpy.Audio()
audio.load("bg", "music.mp3")
audio.play("bg", loop=-1)
audio.set_volume("bg", 0.5)

Available methods:

  • load(name, file_path) — load an audio file
  • play(name, loop=0) — start playback
  • stop(name) — stop a specific sound
  • stop_all() — stop everything
  • is_playing(name=None) — check whether a sound is active
  • set_volume(name, volume) — update a volume level
  • pause(name) — pause playback
  • resume(name) — resume playback
  • fade_out(name, duration) — fade the sound out
  • fade_in(name, duration, loop=0) — fade in and optionally loop
  • play_for_time(name, duration) — play for a set length and stop automatically

Terminal utilities

Animpy also includes helpers for terminal output.

animpy.hide_cursor()
animpy.show_cursor()
animpy.clear_screen()
animpy.print_centered("Centered")
animpy.print_with_color("Colored", r=255, g=0, b=0)
animpy.print_panel("Hello", title="Info")

Available helpers:

  • lerp(start, end, t) — linear interpolation
  • hide_cursor() / show_cursor()
  • clear_screen()
  • print_centered(text)
  • print_with_color(text, r, g, b)
  • print_panel(text, title="Panel", style="bold white on blue")
  • ANSI color constants such as animpy.ANSI["red"] and animpy.ANSI["bg_blue"]
  • terminal size helpers such as get_terminal_size(), set_terminal_size(columns, lines), reset_terminal_size(), get_terminal_width(), and get_terminal_height()

Example projects

The repository contains examples for:

  • basic movement and interpolation
  • loading screens
  • visual effects
  • physics demos
  • player controls
  • collision and tag-style games
  • audio playback

You can browse the examples folder in the project repository for complete scripts.

Version history

v2.6.0

Added a new Camera class for scene view transformation and object tracking. All existing particle and utility methods now work seamlessly with camera-enabled scenes.

New Camera class:

  • Camera(position, target=None) — Constructor that creates a camera at a specific position with an optional target
    • position — tuple of (x, y) representing the camera's current location
    • target — optional object or position to point the camera at; defaults to None

Camera methods:

  • move(new_position) — Directly set the camera position to a new tuple (x, y)
  • look_at(new_target) — Point the camera at a new target position or object
  • follow(target_object) — Continuously track a Text or object with x and y properties
  • get_view_matrix() — Return the current camera view as a tuple (x, y)

Scene camera support:

  • Scene.camera — New optional property to attach a Camera instance
    • Assign a Camera to enable camera-based rendering offsets
    • When set, all objects render relative to the camera's viewpoint
    • Works with all scene objects: Text, Particles, Shapes, Groups

Particle class methods (now camera-compatible):

  • update(delta_time) — Advance particle age and position
  • emit(scene) — Add a single particle instance to the scene
  • burst(scene, count=10, speed=1.0) — Create multiple particles with random velocities in all directions
  • change_rgb_values(r, g, b) — Update particle color
  • set_velocity(vx, vy) — Set particle velocity directly
  • apply_force(fx, fy) — Add velocity changes via force
  • set_color(r, g, b) — Alias for changing color
  • reset(x, y, lifetime=None) — Reset particle position and age
  • is_alive() — Check if particle is still active
  • update_all(delta_time) — Update all child particles created by burst
  • is_dead() — Check if all tracked particles have expired

Particle Presets class (now camera-compatible):

  • Presets.create_explosion(x, y, count=20, speed=1.0, lifetime=1.0) — Create an explosion effect
  • Presets.create_smoke(x, y, count=10, speed=0.5, lifetime=2.0) — Create a smoke effect
  • Presets.create_firework(x, y, count=30, speed=2.0, lifetime=1.5) — Create a firework effect

Utility functions (now camera-compatible):

  • lerp(start, end, t) — Linear interpolation between start and end values
  • hide_cursor() — Hide the terminal cursor
  • show_cursor() — Show the terminal cursor
  • clear_screen() — Clear terminal display
  • print_panel(text, title="Panel", style="bold white on blue") — Print text in a styled panel
  • print_centered(text) — Print text centered in the terminal
  • print_with_color(text, r, g, b) — Print colored text using RGB values
  • get_terminal_size() — Return current terminal dimensions
  • set_terminal_size(columns, lines) — Set terminal size
  • reset_terminal_size() — Reset terminal size to defaults
  • get_terminal_width() — Get terminal column count
  • get_terminal_height() — Get terminal line count
  • ANSI — Dictionary of ANSI color and style codes for advanced terminal formatting

v2.5.0

  • Added coordinate helpers such as Coords.distance_to() and Coords.offset()
  • Added Keyframe and KeyChains helpers for path-based motion
  • Added Audio.pause(), Audio.resume(), Audio.fade_in(), and Audio.fade_out()
  • Added Group.clear(), Group.contains(), and Group.find_by_color()
  • Added particle helpers such as set_velocity(), apply_force(), set_color(), reset(), and is_alive()
  • Added scene helpers such as clear_items(), count_items(), and find_items_at()
  • Added shape builders square() and donut()
  • Added text convenience setters such as set_frame(), set_text(), set_position(), move_to(), and set_color()

v2.1.0

  • Added Shapes.line(), Shapes.ellipse(), Shapes.heart(), and Shapes.triangle()
  • Added clear_screen(), print_centered(), and print_with_color()

v2.0.0

  • Added PhysicsScene for gravity, friction, bounce, and force-driven motion
  • Added EffectText animation helpers such as fade_out_text(), lerp_text(), and pulse_text()
  • Added interactive scene helpers such as limit_to_bounds(), quick_exit(), and limit_group_to_bounds()

Support

If you enjoy Animpy, please consider starring the project on GitHub:

https://github.com/13DoesPython/animpy

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

animpy-3.0.0.tar.gz (21.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

animpy-3.0.0-py3-none-any.whl (18.0 kB view details)

Uploaded Python 3

File details

Details for the file animpy-3.0.0.tar.gz.

File metadata

  • Download URL: animpy-3.0.0.tar.gz
  • Upload date:
  • Size: 21.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for animpy-3.0.0.tar.gz
Algorithm Hash digest
SHA256 21ba5b249cec66dfd74aae278530db4486fc9450e7b330da0a8b35de2a136628
MD5 93f6ff937d7c40d0e5d4a2446fcd79d2
BLAKE2b-256 fe3b278b6ca20b9ad1feeb2c76fe87bd5fbf234251d96f973ba693e958f41d88

See more details on using hashes here.

File details

Details for the file animpy-3.0.0-py3-none-any.whl.

File metadata

  • Download URL: animpy-3.0.0-py3-none-any.whl
  • Upload date:
  • Size: 18.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for animpy-3.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 273b241ce02ee7f22afa090dbf31e9613c08fbfec09a69466f2a1399f1a0a6fc
MD5 0cd67c36f9035bcf31fddffa64712d70
BLAKE2b-256 082eeb3a7f059e8693ca75649baa74785338e0fcaf58a51399cb17a0eb0819a9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page