Crate thin_engine

Source
Expand description

A thin game engine (hence the name). Drawing done with glium, game variables done with glium-types, windowing done with winit and input done with winit-input-map. It has easy fxaa support and low boilerplate despite having lots of control.

use thin_engine::{prelude::*, meshes::screen};
use std::{cell::RefCell, rc::Rc};
use Action::*;

#[derive(Hash, PartialEq, Eq, Clone, Copy)]
enum Action {
    Left,
    Right,
    Jump,
    Exit
}
let event_loop = EventLoop::new().unwrap();
event_loop.set_control_flow(ControlFlow::Poll);
let mut input = { use base_input_codes::*; input_map!(
    (Left,  KeyA, MouseButton::Left,  ArrowLeft,  DPadLeft),
    (Right, KeyD, MouseButton::Right, ArrowRight, DPadRight),
    (Jump,  KeyW, ArrowUp, Space, GamepadInput::South),
    (Exit,  Escape, GamepadInput::Start)
)};

struct Graphics {
    box_indices: IndexBuffer<u32>,
    box_vertices: VertexBuffer<Vertex>,
    box_uvs: VertexBuffer<TextureCoords>,
    box_normals: VertexBuffer<Normal>,
    box_shader: Program
}
let graphics: Rc<RefCell<Option<Graphics>>> = Rc::default();
let graphics_setup = graphics.clone();

let mut player_pos = Vec2::ZERO;
let mut player_gravity = 0.0;
let mut player_can_jump = true;

// camera matrix must be inverse
let camera = Mat4::from_scale(Vec3::splat(10.0)).inverse();
 
let settings = Settings::from_fps(60); // target of 60 fps
let mut frame_start = Instant::now();
thin_engine::builder(input).with_setup(move |display, window, _| {
    // some computers will panic when a vertex buffer is used but not passed a value. so we must
    // initialise empty vertex buffers.
    let (box_indices, box_vertices, box_uvs, box_normals) = mesh!(
        display, &screen::INDICES, &screen::VERTICES,
        &[] as &[TextureCoords; 0], &[] as &[Normal; 0]
    );
    let box_shader = Program::from_source(
        display, shaders::VERTEX, 
        "#version 140
        out vec4 colour;
        void main() {
            colour = vec4(1.0, 0.0, 0.0, 1.0);
        }", None
    ).unwrap();
    graphics_setup.replace(Some(Graphics {
        box_vertices, box_uvs, box_normals, box_indices, box_shader
    }));
}).with_update(move |input, display, _settings, target, window| {
    // gets time between frames
    let delta_time = frame_start.elapsed().as_secs_f32();
    frame_start = Instant::now();
     
    if input.pressed(Exit) { target.exit() }

    // game logic
    player_pos.x += input.axis(Right, Left) * 10.0 * delta_time;
    player_gravity += delta_time * 50.0;
    player_pos.y -= player_gravity * delta_time;
    if player_pos.y < 0.0 {
        player_pos.y = 0.0;
        player_can_jump = true;
    }
    if player_can_jump && input.pressed(Jump) {
        player_gravity = -20.0;
        player_can_jump = false;
    }

    let graphics = graphics.borrow();
    let Graphics {
        box_vertices, box_uvs, box_normals, box_indices, box_shader
    } = graphics.as_ref().unwrap();
    // set up frame
    let mut frame = display.draw();
    let view2d = Mat4::view_matrix_2d(frame.get_dimensions());

    // draw
    frame.clear_color(0.0, 0.0, 0.0, 1.0);
    frame.draw(
        (box_vertices, box_uvs, box_normals), box_indices,
        box_shader, &uniform! {
            view: view2d, camera: camera,
            model: Mat4::from_pos(player_pos.extend(0.0)),
        }, &DrawParameters::default()
    );
    window.pre_present_notify();
    frame.finish().unwrap();
}).with_settings(Settings::from_fps(60))
    .build(event_loop).unwrap();

Re-exports§

pub use gilrs;
pub use glium;
pub use glium_types;
pub use winit;
pub use winit_input_map as input_map;

Modules§

application
meshes
prelude
shaders

Structs§

ResizableDepthTexture2d
resizable depth texture. use with gliums SimpleFrameBuffer::WithDepthTexture() to create a texture you can draw on! usefull for things like fog and fxaa.
ResizableTexture2d
resizable depth texture. recomended to use with gliums SimpleFrameBuffer to draw onto a texture you can use in another shader! usefull for fxaa
Settings
run time settings for thin engine including gamepad settings (through gilrs) and fps settings. when running default() the gamepads may fail to initialise and the program will continue running after printing the error. if this is undesirable use with_gamepads() instead.

Functions§

builder

Type Aliases§

Display