1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//! This crate has been renamed to [`chuot`](https://docs.rs/chuot/latest/chuot/) and is deprecated. If you want to take over the crate name send me a message!

pub mod assets;
#[cfg(feature = "audio")]
pub mod audio;
pub mod canvas;
#[cfg(feature = "dialogue")]
pub mod dialogue;
pub mod font;
pub mod gui;
pub mod math;
#[cfg(feature = "physics")]
pub mod physics;
pub mod sprite;
pub mod window;

pub use assets::{asset, asset_owned};
/// Re-export taffy types.
pub use taffy;
/// Re-export vek types.
pub use vek;
pub use window::window;

use canvas::Canvas;
use miette::Result;
use vek::Vec2;
use window::{Input, WindowConfig};

/// Setup a game with a shared state and run it.
///
/// This is only a helper for constructing a global game state around the [`window`] function, which can also be easily used standalone.
pub trait PixelGame: Sized
where
    Self: 'static,
{
    /// Update loop, called every update tick.
    ///
    /// # Arguments
    ///
    /// * `input` - Input helper that can be used to handle different input states.
    /// * `mouse_pos` - Mouse position on the buffer if `Some`, if `None` mouse is outside of the buffer, not necessarily the window.
    /// * `dt` - Delta time, time in seconds since the last update call. Can be used to handle physics.
    ///
    /// # Returns
    ///
    /// * `true` if the window and thus the game should be closed
    fn update(&mut self, input: &Input, mouse_pos: Option<Vec2<usize>>, dt: f32) -> bool;

    /// Render loop, called every render tick.
    ///
    /// # Arguments
    ///
    /// * `canvas` - Pixel buffer where all the graphics are rendered on.
    fn render(&mut self, canvas: &mut Canvas<'_>);

    /// Run the game, spawning the window.
    ///
    /// # Arguments
    ///
    /// * `window_config` - Configuration for the window, can be used to set the buffer size, the window title and other things.
    fn run(self, window_config: WindowConfig) -> Result<()> {
        window::window(
            self,
            window_config,
            |state, input, mouse_pos, dt| state.update(input, mouse_pos, dt),
            |state, canvas, _dt| state.render(canvas),
        )
    }
}