Skip to main content

Level

Struct Level 

Source
pub struct Level { /* private fields */ }
Expand description

Tiles on a grid, with refills. Outside the grid, the sides and the top are open air, and below the bottom the character falls out. Its parts are read and changed through methods, which keep them consistent (the grid with its size, the refills with the tile size).

Implementations§

Source§

impl Level

Source

pub fn draw_debug(&self, p: &mut Painter<'_>, origin: [f32; 2], scale: f32)

Draw the tiles and the dash refills that are there with p, the level’s top-left at origin (window pixels), scale window pixels per unit.

Source§

impl Level

Source

pub fn parse(rows: &[&str]) -> Self

Parse a level from tile rows (see DEMO): # solid, = one-way platform, * dash refill, P spawn, anything else air. Panics on ragged rows: levels written in code should fail loudly on a typo.

Source

pub fn parse_with(rows: &[&str], tile: impl Fn(char) -> Option<Tile>) -> Self

Like Level::parse, with characters of your own: tile(c) is asked first for each one, and a Some wins over the built-in meaning (so Some(Tile::Custom(0)) for ^ makes spikes, and Some(Tile::Empty) for * leaves the refills out). A spawn marker of your own: Level::find it and Level::set_spawn_tile there.

use game_toolkit_platformer::sim::{Level, Rect, Tile};

const SPIKES: u8 = 0;
let level = Level::parse_with(&["....", ".^^.", "####"], |c| match c {
    '^' => Some(Tile::Custom(SPIKES)),
    _ => None,
});
let feet = Rect { x: 10, y: 4, w: 6, h: 12 };
assert!(level.tiles_touching(feet).any(|(_, _, t)| t == Tile::Custom(SPIKES)));

// `S`, a start pad of your own, is the spawn.
const PAD: u8 = 1;
let mut level = Level::parse_with(&["..S.", "####"], |c| (c == 'S').then_some(Tile::Custom(PAD)));
let (tx, ty) = level.find(Tile::Custom(PAD)).unwrap();
level.set_spawn_tile(tx, ty);
assert_eq!(level.spawn_tile(), (2, 0));
Source

pub fn from_fn(w: i32, h: i32, tile: impl Fn(i32, i32) -> Tile) -> Self

A w x h level whose tile at x, y is tile(x, y): the way in from your own tilemap. No refills, the spawn at the top-left; add them as you like.

Source

pub fn with_tile_size(self, size: i32) -> Self

This level with tiles of size units (refills scaled along). For a tilemap whose tiles are bigger than the feel’s 8 units; to keep the feel at any tile size, keep 8-unit tiles and draw them scaled, or use a Builder::scale with your own terrain.

Source

pub fn define(&mut self, id: u8, tile: CustomTile)

Make custom tile id tile to the movement: solid ground of some Surface (ice, a conveyor, a wall that can’t be climbed), a one-way platform (CustomTile::platform: a bouncy ledge), or air again with CustomTile::default().

use game_toolkit_platformer::sim::{CustomTile, Level, Rect, Surface, Tile};

const ICE: u8 = 0;
let mut level = Level::parse_with(&["....", "~~~~"], |c| (c == '~').then_some(Tile::Custom(ICE)));
level.define(ICE, CustomTile::solid(Surface { friction: 0.1, ..Surface::DEFAULT }));
let feet = Rect { x: 8, y: 8, w: 6, h: 1 };
assert!(level.solid_tile(1, 1));
assert_eq!(level.surface_at(feet).friction, 0.1);
Source

pub fn custom_tile(&self, id: u8) -> CustomTile

What custom tile id is to the movement (air unless Level::defined).

Source

pub fn width(&self) -> i32

Width in tiles.

Source

pub fn height(&self) -> i32

Height in tiles.

Source

pub fn tile_size(&self) -> i32

The size of a tile in units: TILE unless Level::with_tile_size changed it.

Source

pub fn spawn_tile(&self) -> (i32, i32)

The spawn tile (the character stands on the tile below it; see Level::start).

Source

pub fn set_spawn_tile(&mut self, tx: i32, ty: i32)

Move the spawn to tile tx, ty: a marker of your own (see Level::parse_with).

Source

pub fn refills(&self) -> &[Crystal]

The dash refills, with whether each is there (Crystal::ready): for drawing.

Source

pub fn add_refill(&mut self, tx: i32, ty: i32)

Add a dash refill filling tile tx, ty (of this level’s tile size).

Source

pub fn refill_back(&self) -> f32

Seconds before a used refill comes back.

Source

pub fn set_refill_back(&mut self, seconds: f32)

Make used refills come back after seconds.

Source

pub fn find(&self, tile: Tile) -> Option<(i32, i32)>

The first tile that is tile, row by row: where a marker of your own is.

Source

pub fn demo() -> Self

The demo level.

Source

pub fn start(&self) -> Spot

Where a character starts: standing on the bottom of the spawn tile, centered on it (units).

Source

pub fn tile(&self, tx: i32, ty: i32) -> Tile

The tile at tx, ty; outside the grid, air.

Source

pub fn set(&mut self, tx: i32, ty: i32, tile: Tile)

Change the tile at tx, ty (outside the grid: nothing happens).

Source

pub fn tiles_touching( &self, r: Rect, ) -> impl Iterator<Item = (i32, i32, Tile)> + '_

The tiles r overlaps, as (tx, ty, tile), row by row: what the character’s hitbox touches (spikes, water, the goal), with Tile::Custom tiles of your own.

Source

pub fn touches(&self, hitboxes: &[Rect], tile: Tile) -> Option<Rect>

The first of hitboxes that touches a tile, if any: pass Platformer::hitboxes to test every step of the last frame. The result is a copy, so you can act on the character right away: if level.touches(hero.hitboxes(), SPIKES).is_some() { hero.respawn(); }.

Source

pub fn solid_tile(&self, tx: i32, ty: i32) -> bool

Whether tile tx, ty is solid: Tile::Solid, or a custom tile Level::defined solid.

Source

pub fn platform_tile(&self, tx: i32, ty: i32) -> bool

Whether tile tx, ty is a one-way platform: Tile::Platform, or a custom tile Level::defined one.

Source

pub fn surface_at(&self, r: Rect) -> Surface

The surface r touches (the row under the feet, the column beside a wall): of the holding tile under r’s center if there is one, else of the first holding tile it overlaps, else Surface::DEFAULT. The same rule as Grid::surface_of.

Source

pub fn overlaps(&self, r: Rect) -> bool

Whether r overlaps any solid tile (platforms don’t count).

Source

pub fn on_platform(&self, r: Rect) -> bool

Whether r stands exactly on top of a one-way platform.

Source

pub fn floor_y(&self) -> i32

The bottom of the level in units.

Trait Implementations§

Source§

impl Clone for Level

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Level

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for Level

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Level

Source§

impl Terrain for Level

Source§

fn solid(&self, r: Rect) -> bool

Whether r overlaps anything solid (walls, floors, ceilings, moving solids).
Source§

fn platform(&self, r: Rect) -> bool

Whether r stands exactly on top of a one-way platform (its bottom edge on the platform’s top). One-way platforms hold from above, let the character jump up through them, and drop it on down + jump.
Source§

fn refill(&mut self, r: Rect) -> bool

The character’s body r touches a dash refill: use it up and return true (it’s only asked when a dash is spent).
Source§

fn fell_out(&self, r: Rect) -> bool

Whether r is out of the world (fell into a pit).
Source§

fn surface(&self, r: Rect) -> Surface

What kind of ground or wall r touches: the row under the feet while standing, the column beside the body at a wall. Ice, conveyor belts, walls that can’t be climbed, bouncy pads (see Surface). Default: the base’s, or Surface::DEFAULT.
Source§

fn tick(&mut self, dt: f32, _bodies: &[Rect])

This layer’s own update, once per step after the characters moved, with their bodies (one, unless several share the terrain through a crate::Party): let things fall onto them, refills come back, platforms move. Only this layer’s state: Terrain::update runs the bases’ ticks by itself. Default: nothing.
Source§

fn base(&self) -> Option<&dyn Terrain>

The terrain this one builds on, which the defaults forward to, or None. terrain_layer! writes it with Terrain::base_mut and Terrain::as_any_mut. Required, so a wrapper can’t lose its base’s platforms, refills and pits by forgetting it.
Source§

fn as_any_mut(&mut self) -> Option<&mut dyn Any>

This terrain as itself, so an Ability can reach your type through find_mut (break a block, flip a switch): Some(self), which terrain_layer! writes. Default: None, it isn’t found (its Terrain::base still is).
Source§

fn as_any(&self) -> Option<&dyn Any>

Terrain::as_any_mut, to read: what find looks at. terrain_layer! writes both. Default: None.
Source§

fn update(&mut self, dt: f32, bodies: &[Rect])

The whole terrain’s update: Terrain::tick on this layer, then on every base down the chain. Don’t write it; write Terrain::tick. Only an adapter that hands its base something else than it got (converted bodies, say) writes it, and then calls the base’s update.
Source§

fn carry(&self, r: Rect) -> (f32, f32)

How far the solid (or one-way platform) overlapping r moved in the last Terrain::update, in units: moving platforms, elevators. Read more
Source§

fn base_mut(&mut self) -> Option<&mut dyn Terrain>

Terrain::base, to change. Return the same terrain from both (checked in debug builds).

Auto Trait Implementations§

§

impl Freeze for Level

§

impl RefUnwindSafe for Level

§

impl Send for Level

§

impl Sync for Level

§

impl Unpin for Level

§

impl UnsafeUnpin for Level

§

impl UnwindSafe for Level

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync> ⓘ

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more