Sprite System
Relevant source files
The following files were used as context for generating this wiki page:
The Sprite System in guiltty provides a mechanism for placing and moving 2D bitmaps over a Canvas while preserving the underlying background. It is designed to allow pixel-level graphics in a terminal environment, leveraging the Kitty graphics protocol for rendering. The system handles bitmap storage, positioning, and a "save-under/restore-under" logic to prevent visual artifacts like "trails" when sprites move across the screen.
Sources: crates/guiltty-core/src/lib.rs:1-6, README.md:1-10, crates/guiltty-core/src/lib.rs:805-820
Core Components
The Sprite System is built upon three primary data structures that manage image data, positioning, and state preservation.
Bitmap
A Bitmap represents the raw pixel content of a sprite. It uses an RGBA8 color model where each pixel is represented by four bytes (Red, Green, Blue, and Alpha). Bitmaps can be created manually from pixel buffers, generated as solid colors, or loaded from external files (PNG, JPEG, GIF, BMP).
Sources: crates/guiltty-core/src/lib.rs:658-670, crates/guiltty-core/src/lib.rs:704-715
Sprite
The Sprite struct binds a Bitmap to a Point (position) and tracks the DrawnFootprint of its last render. This structure is intended to be moved and redrawn repeatedly.
Sources: crates/guiltty-core/src/lib.rs:805-812
DrawnFootprint
This internal structure stores a copy of the canvas pixels that were covered by the sprite during its last draw_sprite call. It includes the canvas_id to ensure background restoration only occurs on the correct Canvas instance.
Sources: crates/guiltty-core/src/lib.rs:792-801
Architecture and Data Flow
The following diagram illustrates the relationship between a Sprite, its Bitmap, and the Canvas during a drawing operation.
The Sprite System utilizes a Canvas ID to track where a sprite was last drawn, ensuring that background restoration is context-aware.
Sources: crates/guiltty-core/src/lib.rs:88-95, crates/guiltty-core/src/lib.rs:792-812, crates/guiltty-core/src/lib.rs:835-850
Movement and Background Preservation
The system implements a "save-under/restore-under" logic within the Canvas::draw_sprite method. This process ensures that when a sprite moves, the pixels it previously occupied are returned to their original state.
Drawing Logic Flow
- Restore Background: If the sprite has a
last_drawfootprint and thecanvas_idmatches, the pixels stored in the footprint are written back to the canvas. - Clip and Capture: The sprite's new position is clipped to the canvas bounds. The existing pixels in this new area are captured and stored in a new
DrawnFootprint. - Render Sprite: The sprite's bitmap is drawn onto the canvas. Pixels with
alpha == 0are skipped to allow for transparency. - Update State: The sprite's
last_drawis updated with the new footprint.
Background preservation is critical for movement without trails; however, it assumes that no other drawing operations occurred within the sprite's footprint between draw_sprite calls.
Sources: crates/guiltty-core/src/lib.rs:835-885
Image Loading and Conversion
The Bitmap::from_file method handles the ingestion of external image assets. Regardless of the source format, the system converts all images to the project-wide RGBA8 color model.
| Feature | Description | Source |
|---|---|---|
| Supported Formats | PNG, JPEG, GIF, BMP | lib.rs:706 |
| Color Model | RGBA8 (4 bytes per pixel) | lib.rs:658 |
| Alpha Handling | Sources without alpha receive a default opaque (255) alpha | lib.rs:709 |
| Error Handling | Returns Error::ImageLoad for missing or corrupt files | lib.rs:712 |
Sources: crates/guiltty-core/src/lib.rs:704-725, tasks/plan.md:T3
Technical Specifications
Data Structures
// crates/guiltty-core/src/lib.rs:805-809
pub struct Sprite {
bitmap: Bitmap,
position: Point,
last_draw: Option<DrawnFootprint>,
}
// crates/guiltty-core/src/lib.rs:792-799
struct DrawnFootprint {
canvas_id: u64,
x: i64,
y: i64,
width: u32,
height: u32,
pixels: Vec<Color>,
}
Key Methods
| Method | Component | Description |
|---|---|---|
new(bitmap, position) | Sprite | Initializes a sprite with no drawing history. |
move_to(position) | Sprite | Updates the target position for the next draw call. |
draw_sprite(&mut sprite) | Canvas | The main entry point for rendering and background management. |
from_file(path) | Bitmap | Constructor for loading disk-based assets. |
Sources: crates/guiltty-core/src/lib.rs:821-833, crates/guiltty-core/src/lib.rs:835-850, crates/guiltty-core/src/lib.rs:704-710
Implementation Constraints
- Cloning Behavior: Cloning a
Spritecreates a new instance with a copy of the bitmap and position, butlast_drawis set toNone. This prevents a cloned sprite from attempting to restore pixels captured by the original sprite. - Canvas Isolation: The
canvas_idcheck indraw_spriteprevents a sprite from attempting to restore a background captured onCanvas Awhen being drawn onCanvas B. - Rendering Model: The system does not currently support full alpha blending; non-transparent pixels (
alpha != 0) replace the canvas pixels entirely.
Sources: crates/guiltty-core/src/lib.rs:813-820, crates/guiltty-core/src/lib.rs:839-845, crates/guiltty-core/src/lib.rs:872-875
Summary
The Sprite System provides a robust foundation for 2D animation within guiltty. By combining Bitmap management, positional tracking, and automated background restoration, it allows developers to move complex graphical objects across a terminal Canvas with minimal manual state management. Its reliance on the RGBA8 model and strict canvas identification ensures consistency and safety across different rendering contexts.