#![warn(missing_docs)]
#![warn(rustdoc::missing_doc_code_examples)]
pub mod camera;
pub mod collider;
pub mod component;
pub mod gl;
pub mod input;
pub mod math;
pub mod mesh;
pub mod particle;
pub mod renderer;
pub mod shader;
pub mod texture;
pub mod transform;
pub mod ui;
pub mod utils;
pub mod web;
use wasm_bindgen::prelude::*;
use camera::Camera;
use gl::GL;
use input::InputManager;
pub use math::*;
use particle::ParticleSystem;
use renderer::Renderer;
use shader::Shader;
use texture::Texture;
use transform::Transform;
use utils::set_panic_hook;
use web::Canvas;
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[wasm_bindgen]
pub struct Application {
renderer: Renderer,
input: InputManager,
}
impl Default for Application {
fn default() -> Self {
set_panic_hook();
Self {
renderer: Renderer::default(),
input: InputManager::new(),
}
}
}
#[allow(clippy::unused_unit)]
#[wasm_bindgen]
impl Application {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
Self::default()
}
#[wasm_bindgen]
pub fn init(&mut self) {
let renderer = &mut self.renderer;
renderer
.gl
.blend_func(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA);
renderer.gl.enable(GL::BLEND);
renderer.init_shader();
let u_tex0 = renderer.program.get_uniform_location(&renderer.gl, "uTex0");
renderer.gl.uniform1i(u_tex0.as_ref(), 0);
renderer.add_texture("TILEMAP", Texture::new_with_texture_id(&renderer.gl, 0));
renderer.add_texture("SHREK", Texture::new_with_texture_id(&renderer.gl, 1));
renderer.use_texture("WHITE");
let simple = ParticleSystem::new_from_emission_and_position(
particle::ParticleProps::default(),
0.0,
0.0,
);
renderer.add_component("DEFAULT", Box::new(simple));
let fire = ParticleSystem::new_from_emission_and_position(
particle::ParticleProps::fire(),
-5.0,
0.0,
);
renderer.add_component("FIRE", Box::new(fire));
let smoke = ParticleSystem::new_from_emission_and_position(
particle::ParticleProps::smoke(),
5.0,
0.0,
);
renderer.add_component("SMOKE", Box::new(smoke));
renderer.init_components();
}
#[wasm_bindgen]
pub fn resize(&mut self, width: f32, height: f32) {
self.renderer.resize(width, height);
}
#[wasm_bindgen]
pub fn input(&mut self, key_code: u8, is_down: bool) {
if is_down {
self.input.key_down(key_code);
} else {
self.input.key_up(key_code);
}
}
#[wasm_bindgen]
pub fn mouse_move(&mut self, mouse_x: i32, mouse_y: i32) {
let (x, y) = self
.renderer
.camera
.screen_to_world_coordinates(mouse_x as f32, mouse_y as f32);
self.input.mouse_position = Vec2::new(x, y);
}
#[wasm_bindgen]
pub fn render(&mut self, delta_time: u32) {
let renderer = &mut self.renderer;
let delta_time = delta_time as f32 / 1000.0;
renderer.clear([0.5, 0.2, 0.3, 1.0]);
if self.input.get_key_state(b'R') {
renderer.init_components();
}
if self.input.get_key_state(b'1') {
renderer
.get_mut_component::<ParticleSystem>("FIRE")
.unwrap()
.toggle_alive();
}
if self.input.get_key_state(b'2') {
renderer
.get_mut_component::<ParticleSystem>("DEFAULT")
.unwrap()
.toggle_alive();
}
if self.input.get_key_state(b'3') {
renderer
.get_mut_component::<ParticleSystem>("SMOKE")
.unwrap()
.toggle_alive();
}
let horizontal =
self.input.get_key_state(b'D') as i32 - self.input.get_key_state(b'A') as i32;
let vertical =
self.input.get_key_state(b'S') as i32 - self.input.get_key_state(b'W') as i32;
let simple = renderer
.get_mut_component::<ParticleSystem>("DEFAULT")
.unwrap();
simple.transform.position = self.input.mouse_position;
let smoke = renderer
.get_mut_component::<ParticleSystem>("SMOKE")
.unwrap();
if smoke.alive {
smoke.transform.position +=
Vec2::new(horizontal as f32 * delta_time, vertical as f32 * delta_time);
}
renderer.update_components(delta_time);
renderer.draw_components();
}
}