diff options
Diffstat (limited to 'src/game.rs')
| -rw-r--r-- | src/game.rs | 178 |
1 files changed, 153 insertions, 25 deletions
diff --git a/src/game.rs b/src/game.rs index 1abe66e..0596a2b 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,11 +1,16 @@ #![allow(dead_code, unused_variables)] -use std::collections::HashMap; +use std::{collections::HashMap, f32::consts::PI}; use teleia::*; +use crate::room; + +const MOUSE_SENSITIVITY: f32 = 0.01; +const PLAYER_SPEED: f32 = 0.1; +const PLAYER_RADIUS: f32 = 0.5; + struct Assets { font: font::Bitmap, - shader_flat: shader::Shader, - mesh_square: mesh::Mesh, + mesh_cube: mesh::Mesh, texture_test: texture::Texture, } @@ -13,53 +18,176 @@ impl Assets { fn new(ctx: &context::Context) -> Self { Self { font: font::Bitmap::default(ctx), - shader_flat: shader::Shader::new( - ctx, - include_str!("assets/shaders/flat/vert.glsl"), - include_str!("assets/shaders/flat/frag.glsl"), - ), - mesh_square: mesh::Mesh::from_obj(ctx, include_bytes!("assets/meshes/square.obj")), + mesh_cube: mesh::Mesh::from_obj(ctx, include_bytes!("assets/meshes/cube.obj")), texture_test: texture::Texture::new(ctx, include_bytes!("assets/textures/test.png")), } } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Mode { + Titlescreen, + Game, +} + pub struct Game { + mode: Mode, assets: Assets, + room_path: String, + room: room::Room, + mouse: (i32, i32), + camera_pitch: f32, + camera_yaw: f32, + player_pos: glam::Vec3, } impl Game { - pub fn new(ctx: &context::Context) -> Self { + pub fn new(ctx: &context::Context, room_path: &str) -> Self { Self { + mode: Mode::Titlescreen, assets: Assets::new(ctx), + room_path: room_path.to_owned(), + room: room::Room::new(ctx, shader::Shader::new(ctx, + include_str!("assets/shaders/plane/vert.glsl"), + include_str!("assets/shaders/plane/frag.glsl"), + )), + mouse: (ctx.render_width as i32 / 2, ctx.render_height as i32 / 2), + camera_pitch: 0.0, + camera_yaw: 0.0, + player_pos: glam::Vec3::new(0.0, 0.0, 0.0), } } + fn looking_at_art(&self, ctx: &context::Context, st: &mut state::State) -> bool { + let q = glam::Quat::from_rotation_y(self.camera_yaw); + let dir = q.mul_vec3(glam::Vec3::new(0.0, 0.0, 1.0)); + let p = self.player_pos + dir; + p.distance(glam::Vec3::ZERO) < 2.0 + } + fn player_height(&self) -> f32 { + 1.0 / self.room.config.size + } + fn player_speed(&self) -> f32 { + PLAYER_SPEED / self.room.config.size * self.room.config.speed + } } impl teleia::state::Game for Game { + fn initialize(&mut self, ctx: &context::Context, st: &mut state::State) -> Erm<()> { + Ok(()) + } fn initialize_audio(&self, ctx: &context::Context, st: &state::State, actx: &audio::Context) -> HashMap<String, audio::Audio> { HashMap::from_iter(vec![ - ("test".to_owned(), audio::Audio::new(&actx, include_bytes!("assets/audio/test.wav"))), + ("mrbeast".to_owned(), audio::Audio::new(&actx, include_bytes!("assets/audio/mrbeast.mp3"))), ]) } - fn update(&mut self, _ctx: &context::Context, _st: &mut state::State) -> Erm<()> { + fn finish_title(&mut self, ctx: &context::Context, st: &mut state::State) -> Erm<()> { + if self.mode == Mode::Titlescreen { + self.mode = Mode::Game; + ctx.lock_mouse(); + // TODO + if cfg!(target_arch = "wasm32") { + self.room.load_from_bytes(ctx, st, + Some(include_bytes!("/home/llll/src/bapalon/DATA/NIGHT_1/ROOM_4/room.ini")), + include_bytes!("/home/llll/src/bapalon/DATA/NIGHT_1/ROOM_4/FLOOR.png"), + include_bytes!("/home/llll/src/bapalon/DATA/NIGHT_1/ROOM_4/WALL.png"), + include_bytes!("/home/llll/src/bapalon/DATA/NIGHT_1/ROOM_4/ROOF.png"), + include_bytes!("/home/llll/src/bapalon/DATA/NIGHT_1/ROOM_4/ART.png"), + include_bytes!("/home/llll/src/bapalon/DATA/NIGHT_1/ROOM_4/CREDIT.png"), + Some(include_bytes!("/home/llll/src/bapalon/DATA/NIGHT_1/ROOM_4/MINI.png")), + Some(include_bytes!("/home/llll/src/bapalon/DATA/NIGHT_1/ROOM_4/INTERACT.png")), + Some(include_bytes!("/home/llll/src/bapalon/DATA/NIGHT_1/ROOM_4/LAYER.png")), + Some(include_bytes!("/home/llll/src/bapalon/DATA/NIGHT_1/ROOM_4/MUSIC.mp3")), + Some(include_bytes!("/home/llll/src/bapalon/DATA/NIGHT_1/ROOM_4/FOOT.wav")), + )?; + } else { + self.room.load(ctx, st, &self.room_path)?; + } + } + Ok(()) + } + fn mouse_press(&mut self, ctx: &context::Context, st: &mut state::State) -> Erm<()> { + match self.mode { + Mode::Titlescreen => { + } + Mode::Game => { + self.room.credit_mode.toggle(st.tick); + }, + } + Ok(()) + } + fn mouse_move(&mut self, ctx: &context::Context, st: &mut state::State, x: i32, y: i32) -> Erm<()> { + match self.mode { + Mode::Titlescreen => { + } + Mode::Game => { + let dx = x - self.mouse.0; + let dy = y - self.mouse.1; + self.camera_yaw += dx as f32 * MOUSE_SENSITIVITY; + self.camera_pitch += dy as f32 * MOUSE_SENSITIVITY; + self.camera_pitch = self.camera_pitch.clamp(-PI/2.0 + 0.001, PI/2.0 - 0.001); + self.mouse = (x, y); + } + } + Ok(()) + } + fn update(&mut self, ctx: &context::Context, st: &mut state::State) -> Erm<()> { + match self.mode { + Mode::Titlescreen => { + } + Mode::Game => { + let mut player_dir = glam::Vec3::ZERO; + if st.keys.up() { player_dir += glam::Vec3::new(0.0, 0.0, 1.0); } + if st.keys.down() { player_dir += glam::Vec3::new(0.0, 0.0, -1.0); } + if st.keys.left() { player_dir += glam::Vec3::new(-1.0, 0.0, 0.0); } + if st.keys.right() { player_dir += glam::Vec3::new(1.0, 0.0, 0.0); } + if player_dir != glam::Vec3::ZERO { + self.room.footstep(ctx, st)?; + player_dir = player_dir.normalize(); + self.player_pos += self.player_speed() + * glam::Quat::from_rotation_y(self.camera_yaw).mul_vec3(player_dir); + self.player_pos.x = self.player_pos.x.clamp( + -room::PLANE_SIZE + PLAYER_RADIUS, + room::PLANE_SIZE - PLAYER_RADIUS + ); + self.player_pos.z = self.player_pos.z.clamp( + -room::PLANE_SIZE + PLAYER_RADIUS, + room::PLANE_SIZE - PLAYER_RADIUS + ); + } + if self.looking_at_art(ctx, st) { + if !self.room.interact_mode.is_active() { + self.room.interact_mode.toggle(st.tick); + } + } else { + if self.room.interact_mode.is_active() { + self.room.interact_mode.toggle(st.tick); + } + } + let q = glam::Quat::from_euler(glam::EulerRot::YXZ, self.camera_yaw, self.camera_pitch, 0.0); + let dir = q.mul_vec3(glam::Vec3::new(0.0, 0.0, 1.0)); + st.move_camera(ctx, + &(self.player_pos + glam::Vec3::new(0.0, self.player_height(), 0.0)), + &dir, + &glam::Vec3::new(0.0, 1.0, 0.0), + ); + } + } Ok(()) } fn render(&mut self, ctx: &context::Context, st: &mut state::State) -> Erm<()> { ctx.clear(); - self.assets.font.render_text( - ctx, st, - &glam::Vec2::new(0.0, 0.0), - "hello computer", - ); - st.bind_2d(ctx, &self.assets.shader_flat); - self.assets.texture_test.bind(ctx); - self.assets.shader_flat.set_position_2d( - ctx, st, - &glam::Vec2::new(40.0, 40.0), - &glam::Vec2::new(16.0, 16.0), - ); - self.assets.mesh_square.render(ctx); + match self.mode { + Mode::Titlescreen => { + self.assets.font.render_text( + ctx, st, + &glam::Vec2::new(0.0, 0.0), + "click to continue", + ); + } + Mode::Game => { + self.room.render(ctx, st, self.camera_yaw)?; + } + } Ok(()) } } |
