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: ansim::Intentin per step,sim::Events out. Every feel number and ability switch is insim::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 anIntent, through aSchemeof keys and buttons.- hero
- The hero’s binding to the animation controller: which sprites exist (
sprite), the state graph over them (graph), and theHeroDriverthat 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 thetoolkitfeature) 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
Terrainlayer inside itsimpl Terrainblock:Terrain::baseandTerrain::base_mutreturning the field named (a name or a tuple index; left out: no base), andTerrain::as_any_mutandTerrain::as_anyreturning the terrain itself, sofind_mutfinds it.