use crate::angel_shifts; use crate::colliders; use crate::colors; use crate::components; use crate::entities; use crate::gamestate; use crate::resources; use crate::svg_loader; use crate::systems; use crate::utils; pub struct InGameState { gui_svg: web_sys::SvgElement, world: legion::World, resources: legion::Resources, schedule: legion::Schedule, registered_images: Vec, } impl InGameState { pub fn new( level: svg_loader::SvgLevel, mut rendering: resources::Rendering, player: components::Player, assigned_shift: angel_shifts::AngelShift, ) -> InGameState { let sanity_bar = utils::get_element_by_id("sanity-amount").unwrap(); let foreground = rendering.register_image(level.foreground_image.clone()); let background = rendering.register_image(level.background_image.clone()); let mut resources = legion::Resources::default(); let mut world = legion::World::default(); resources.insert(resources::Clock::new()); resources.insert(rendering); resources.insert(resources::Camera::new(1920.0, 1080.0)); resources.insert(colliders::CollisionWorld::new()); let player = entities::create_player(&mut world, &resources, &level, player); resources.insert(resources::Player(player)); level.apply_colliders(&mut world); let mut schedule_builder = legion::Schedule::builder(); schedule_builder .add_system(colliders::synchronize_collisision_world_system()) .flush() .add_system(colliders::update_collision_world_system()) .flush() .add_thread_local(systems::move_movable_system()) .flush(); assigned_shift.init_gameworld(&mut world, &mut resources, &mut schedule_builder, &level); schedule_builder .flush() .add_thread_local(systems::move_camera_to_player_system()) .add_thread_local(systems::camera_system()) .add_thread_local(systems::update_sanity_bar_system(sanity_bar)) .add_thread_local(systems::draw_level_layer_system(background)) .add_thread_local(systems::draw_sprites_system()) .add_thread_local(systems::draw_level_layer_system(foreground)) .add_thread_local(systems::draw_tmp_matebottledrop_system()) // .add_thread_local(systems::draw_debug_colliders_system()) ; let schedule = schedule_builder.build(); InGameState { gui_svg: utils::get_element_by_id("ingame-ui").unwrap(), world, resources, schedule, registered_images: vec![foreground, background], } } } impl gamestate::State for InGameState { fn init(&mut self, mut init: gamestate::StateInitializer) -> gamestate::Transition { self.gui_svg .style() .set_property("display", "block") .unwrap(); init.register_keyevents(); gamestate::Transition::Loop } fn deinit(&mut self) { let mut rendering = self.resources.get_mut::().unwrap(); for image in &self.registered_images { rendering.deregister_image(image); } rendering.set_transform(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); self.gui_svg .style() .set_property("display", "none") .unwrap(); } fn event(&mut self, event: gamestate::Event) -> gamestate::Transition { use legion::IntoQuery; let player = self.resources.get::().unwrap().0.clone(); let player_movable = <&mut components::Movable>::query() .get_mut(&mut self.world, player) .unwrap(); match event { gamestate::Event::KeyDown("w") => player_movable.velocity.y = -50.0, gamestate::Event::KeyUp("w") => player_movable.velocity.y = 0.0, gamestate::Event::KeyDown("a") => player_movable.velocity.x = -50.0, gamestate::Event::KeyUp("a") => player_movable.velocity.x = 0.0, gamestate::Event::KeyDown("s") => player_movable.velocity.y = 50.0, gamestate::Event::KeyUp("s") => player_movable.velocity.y = 0.0, gamestate::Event::KeyDown("d") => player_movable.velocity.x = 50.0, gamestate::Event::KeyUp("d") => player_movable.velocity.x = 0.0, _ => (), } gamestate::Transition::Keep } fn update(&mut self) -> gamestate::Transition { { let rendering = self.resources.get::().unwrap(); rendering.set_transform(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); rendering.set_fill_style(&colors::BACKGROUND); rendering.fill_rect(0.0, 0.0, 1920.0, 1080.0); } self.schedule.execute(&mut self.world, &mut self.resources); gamestate::Transition::Loop } }