tversteeg / chuot

🐭 AGPL licensed Rust game engine for 2D pixel-art games
http://tversteeg.nl/chuot/
GNU Affero General Public License v3.0
22 stars 1 forks source link
2d game-engine gamedev rust

🐭 Chuột

Build Status Crates.io Documentation License: AGPL-3.0 Dependency Status Downloads Matrix

Website

AGPL licensed and opinionated game engine for 2D pixel-art games.

Features

Goals

Non-Goals

Usage

Using this crate is quite simple, there is a single trait [Game] with two required functions, [Game::update] and [Game::render], that need to be implemented for a game state object.

use chuot::{Config, Context, Game};

struct MyGame;

impl Game for MyGame {
    fn update(&mut self, ctx: Context) {
        // ..
    }

    fn render(&mut self, ctx: Context) {
        // ..
    }
}

// In main

let game = MyGame;

game.run(chuot::load_assets!(), Config::default());

Features

embed-assets

Embed all assets into the binary when building.

Must be enabled when building for the web. If disabled all assets will be loaded from disk.

This will dice all PNG assets into a single tiny optimized PNG atlas. On startup this diced atlas will be efficiently uploaded to the GPU as a single bigger atlas, which will be used for all static sprites.

read-texture (default)

Expose read operations on images, if disabled sprites will be uploaded to the GPU and their data will be removed from memory.

Install Requirements

On Linux you need to install asound2-dev for audio and udev-dev for gamepads:

sudo apt install libasound2-dev libudev-dev

Example

This example will show a window with a counter that's incremented when pressing the left mouse button^left-mouse. The counter is rendered as text^text loaded from a font in the top-left corner. When the 'Escape' key is pressed^escape-key the game will exit and the window will close.

use chuot::{
  Game, Context, Config,
  context::{MouseButton, KeyCode},
};

/// Object holding all game state.
struct MyGame {
  /// A simple counter we increment by clicking on the screen.
  counter: u32,
}

impl Game for MyGame {
  fn update(&mut self, ctx: Context) {
    // ^1
    // Increment the counter when we press the left mouse button
    if ctx.mouse_pressed(MouseButton::Left) {
      self.counter += 1;
    }

    // ^3
    // Exit the game if 'Escape' is pressed
    if ctx.key_pressed(KeyCode::Escape) {
      ctx.exit();
    }
  }

  fn render(&mut self, ctx: Context) {
    // ^2
    // Display the counter with a font called 'font' automatically loaded from the `assets/` directory
    // It will be shown in the top-left corner
    ctx.text("font", &format!("Counter: {}", self.counter)).draw();
  }
}

// In main

// Initialize the game state
let game = MyGame { counter: 0 };

// Run the game until exit is requested
game.run(chuot::load_assets!(), Config::default().with_title("My Game"));

Rotation Algorithms

In the library it's possible to choose between multiple upscale implementations for the single-pass RotSprite algorithm, see the Rust documentation for more information:

Nearest Neighbor

This doesn't apply any extra rotation effects.

Nearest Neighbor

cleanEdge

cleanEdge

Scale3x (default)

Scale3x

Diag2x

Diag2x

Scale2x

Scale2x

Credits