4 releases (2 breaking)
0.3.0 | Nov 13, 2024 |
---|---|
0.2.0 | Nov 13, 2024 |
0.1.1 | Nov 6, 2024 |
0.1.0 | Nov 4, 2024 |
#271 in Game dev
88 downloads per month
Used in tetrotime
96KB
1.5K
SLoC
🎨 Pixel Loop 🔁
Warning: WORK IN PROGRESS
This crate/library is still heavily being worked on. The API is not considered to be stable at this point in time. If you want to follow the development check out the following youtube channel MrJakob.
About
A Rust game loop implementation providing a solid foundation for building games and interactive applications. Inspired by the concepts from Fix Your Timestep, it offers fixed timestep updates with variable rendering, supporting both windowed and terminal-based applications.
Motivation
The idea behind Pixel Loop resonated with me as I have often faced challenges with timing aspects while working on animations from scratch. This project serves as a practical exploration of fixed time game/update loops and lays the groundwork for future experiments and projects.
Installation
Add Pixel Loop to your Cargo.toml
:
[dependencies]
pixel_loop = "*"
Feature Flags
winit
- Enable window-based renderingcrossterm
- Enable terminal-based renderingstb-image
- Enable image loading support for InMemoryCanvas via stb_image
By default all flags are currently enabled. If you only need a specific one, you may only use enable the backend/feature you specifically need, to cut down on compilation time and filesize.
Examples
Terminal Application
Create a simple moving box in your terminal:
use pixel_loop::{run, canvas::CrosstermCanvas, input::CrosstermInputState};
use pixel_loop::color::Color;
use pixel_loop::input::KeyboardKey;
use anyhow::Result;
struct GameState {
box_pos: (i64, i64),
}
fn main() -> Result<()> {
let mut canvas = CrosstermCanvas::new(); // Terminal size
let state = GameState { box_pos: (0, 0) };
let input = CrosstermInputState::new();
run(
60, // Updates per second
state,
input,
canvas,
// Update function - fixed timestep
|_env, state, input, _canvas| {
if input.is_key_down(KeyboardKey::Right) {
state.box_pos.0 += 1;
}
if input.is_key_pressed(KeyboardKey::Q) {
std::process::exit(0);
}
Ok(())
},
// Render function - variable timestep
|_env, state, _input, canvas, _dt| {
canvas.clear_screen(&Color::from_rgb(0, 0, 0));
canvas.filled_rect(
state.box_pos.0,
state.box_pos.1,
5,
5,
&Color::from_rgb(255, 0, 0),
);
canvas.render()?;
Ok(())
},
)
}
Architecture
Game Loop
Pixel Loop implements a fixed timestep game loop that:
- Updates game logic at a constant rate (configurable FPS)
- Renders as fast as possible while maintaining update consistency
- Handles timing and frame limiting automatically
Canvas System
The library provides (currently) three canvas implementations:
PixelsCanvas
: Hardware-accelerated window renderingCrosstermCanvas
: Terminal-based rendering using Unicode charactersInMemoryCanvas
: In-memory buffer for image manipulation
Each canvas (currently) supports:
- Basic shape rendering (rectangles)
- Color management (RGB and HSL)
- Efficient blitting operations
- Custom viewport management
Input System
Input handling is abstracted through traits:
KeyboardState
for basic keyboard inputInputState
for game loop integration- Support for key press, release, and hold states
- Cross-platform compatibility
Note: Mouse integration for window rendering can currently be archieved, but an abstraction has not yet been implemented
Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Inspired by Fix Your Timestep
- Built with pixels and crossterm
Subprojects
This repository housed a couple of different experiment implementations based on
pixel_loop
. Those have mostly have been moved to their own repositories as
the library is now published on crates.io.
You can find the old subprojects here:
- pixel_sand - A sand movement simulator.
- tetrotime - A Tetromino based clock, stopwatch and timer.
- trivial_cli_demo - A trivial demo showing the CLI/Shell Unicode and ANSI based output driver.
- shell_smash - A simple breakout clone running in your Terminal.
- fireworks - Fireworks particle simulation in your Terminal
Dependencies
~6–40MB
~663K SLoC