Skip to main content

Crate game_toolkit_platformer

Crate game_toolkit_platformer 

Source
Expand description

A pluggable platforming controller for game-toolkit: fluid, snappy movement with feel presets, and an animation state graph that follows it.

The quickest start is Platformer: pick a preset, call update each frame with your world as a sim::Terrain (anything that can say what’s solid; sim::Level is a ready-made one), and draw sprite() at position() (or draw_debug until there is art). Underneath, three layers you can also use on their own:

  • sim: the movement. A fixed-step, deterministic body: an sim::Intent in per step, sim::Events out. Every feel number and ability switch is in sim::Tuning; sim::Presets set them toward the feel of Celeste, Hollow Knight, Silksong or Super Meat Boy (an independent project, not affiliated with those games’ makers).
  • anim: the animation controller, independent of any game: parameters, clips, conditions, a graph spec compiled into a validated graph, the animator, drivers.
  • hero: the binding between them for one character: the built-in graph, its sprite numbers, and the driver that turns movement into graph parameters.

With the toolkit feature (on by default), controls reads game-toolkit’s keyboard and gamepad through per-preset control schemes. Without it, nothing here depends on anything but std.

A complete game with a playable character:

use game_toolkit::prelude::*;
use game_toolkit_platformer::prelude::*;

struct MyGame {
    level: Level,
    hero: Platformer,
}

impl Game for MyGame {
    fn init(_ctx: &mut Context) -> Result<Self> {
        let level = Level::demo();
        let hero = Platformer::on(&level, Preset::Precise);
        Ok(Self { level, hero })
    }

    fn update(&mut self, ctx: &mut Context, dt: f32) {
        self.hero.update(&ctx.input, &mut self.level, dt);
        for event in self.hero.drain_events() {
            match event {
                Event::Jumped { .. } => { /* a sound */ }
                Event::Landed { drop, .. } if drop > 48 => { /* a thud, some dust */ }
                _ => {}
            }
        }
    }

    fn render(&mut self, ctx: &mut Context, frame: &mut Frame) {
        let mut p = frame.painter(&mut ctx.gfx);
        p.clear([0.05, 0.04, 0.12, 1.0]);
        self.level.draw_debug(&mut p, [0.0, 0.0], 3.0);
        self.hero.draw_debug(&mut p, [0.0, 0.0], 3.0);
    }
}

run::<MyGame>(AppConfig::default()).unwrap();

Configured through the builder:

use game_toolkit_platformer::prelude::*;

let hero = Platformer::builder()
    .preset(Preset::Snappy)
    .tune(|t| {
        t.air_jumps = 2;
        t.dash_speed = 260.0;
    })
    .controls(Scheme::PRECISE)
    .spawn(Spot::TopLeft(40, 160))
    .respawn(false)
    .build()
    .unwrap();
assert_eq!(hero.tuning().air_jumps, 2);

Re-exports§

pub use party::Party;
pub use platformer::Animate;
pub use platformer::Builder;
pub use platformer::Platformer;

Modules§

anim
A pluggable, configurable animation controller: a state graph over named parameters, independent of what it animates and of how frames are drawn.
controls
Controls: game-toolkit’s keyboard and gamepad input to an Intent, through a Scheme of keys and buttons.
hero
The hero’s binding to the animation controller: which sprites exist (sprite), the state graph over them (graph), and the HeroDriver that turns the simulation into the graph’s parameters.
party
Party: several characters on one terrain, on one clock.
platformer
Platformer: one playable character, plug and play: movement, its animation, and (with the toolkit feature) the controls.
prelude
Everything a game needs to get started: use game_toolkit_platformer::prelude::*;.
sim
The deterministic simulation: a level of solid tiles and the hero moving through it.

Macros§

terrain_layer
Writes the boilerplate of a Terrain layer inside its impl Terrain block: Terrain::base and Terrain::base_mut returning the field named (a name or a tuple index; left out: no base), and Terrain::as_any_mut and Terrain::as_any returning the terrain itself, so find_mut finds it.