use crate::colors; use crate::components; use crate::gamestate; use crate::resources; use crate::states; use crate::utils; pub struct HeavenState { gui_svg: web_sys::SvgElement, node_world: legion::World, resources: legion::Resources, node_schedule: legion::Schedule, player: components::Player, } impl HeavenState { pub fn new(player: Option) -> HeavenState { let (node_world, resources, node_schedule) = init_orbiting_nodes(); let player = player.unwrap_or_else(|| { // Initialize the game as this is the first run. components::Player::new() }); HeavenState { gui_svg: utils::get_element_by_id("heaven-ui").unwrap(), node_world, resources, node_schedule, player, } } } impl gamestate::State for HeavenState { fn init(&mut self, mut init: gamestate::StateInitializer) -> gamestate::Transition { init.register_onclick("heaven-start-shift"); self.gui_svg .style() .set_property("display", "block") .unwrap(); gamestate::Transition::Loop } fn deinit(&mut self) { self.gui_svg .style() .set_property("display", "none") .unwrap(); } fn update(&mut self) -> gamestate::Transition { { let rendering = self.resources.get_mut::().unwrap(); rendering.set_fill_style(&colors::BACKGROUND); rendering.fill_rect(0.0, 0.0, 1920.0, 1080.0); } self.node_schedule .execute(&mut self.node_world, &mut self.resources); gamestate::Transition::Loop } fn event(&mut self, event: gamestate::Event) -> gamestate::Transition { match event { gamestate::Event::MouseClick { target: "heaven-start-shift", .. } => { gamestate::Transition::replace(states::LevelLoadingState::new(self.player.clone())) } event => { crate::console_log!("unknown event {:?}", event); gamestate::Transition::Keep } } } } fn init_orbiting_nodes() -> (legion::World, legion::Resources, legion::Schedule) { let mut resources = legion::Resources::default(); resources.insert(resources::Clock::new()); resources.insert(resources::Rendering::new("game-canvas").unwrap()); let mut node_world = legion::World::default(); let n0 = node_world.push(( components::Node::new(), components::Position::new(800.0, 340.0), components::OrbitBody::new(5.0, 10.0), components::Gravity, )); let n1 = node_world.push(( components::Node::new(), components::Position::new(120.0, 300.0), components::OrbitBody::new(5.0, -5.0), components::Gravity, )); let n2 = node_world.push(( components::Node::new(), components::Position::new(700.0, 740.0), components::OrbitBody::new(8.0, -4.0), components::Gravity, )); let n3 = node_world.push(( components::Node::new(), components::Position::new(340.0, 290.0), components::OrbitBody::new(10.0, 0.0), components::Gravity, )); let n4 = node_world.push(( components::Node::new(), components::Position::new(300.0, 400.0), components::OrbitBody::new(0.0, 10.0), components::Gravity, )); node_world.push((components::Edge::new(n0, n1),)); node_world.push((components::Edge::new(n1, n2),)); node_world.push((components::Edge::new(n0, n2),)); node_world.push((components::Edge::new(n2, n3),)); node_world.push((components::Edge::new(n3, n4),)); node_world.push((components::Edge::new(n0, n4),)); node_world.push((components::TheSun, components::Position::new(600.0, 540.0))); let node_schedule = legion::Schedule::builder() .add_system(components::update_gravity_system()) .add_system(components::update_movement_system()) .add_thread_local(components::update_nodes_system()) .flush() .add_thread_local(components::draw_edges_system()) .add_thread_local(components::draw_nodes_system()) .add_thread_local(components::draw_thesun_system()) .build(); (node_world, resources, node_schedule) }