From 27bcd3a5d28a098506701e1b27b40a86f8579dd9 Mon Sep 17 00:00:00 2001 From: Thomas Forgione Date: Tue, 2 Aug 2022 14:32:52 +0200 Subject: [PATCH] Cleaning --- src/engine/mod.rs | 285 +++++++++++++++++++++----------------------- src/engine/scene.rs | 3 + 2 files changed, 136 insertions(+), 152 deletions(-) diff --git a/src/engine/mod.rs b/src/engine/mod.rs index 9f13999..0c60a05 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -45,69 +45,25 @@ pub struct Engine { /// /// We need Rc in order to deal with events. pub inner: Rc>, - - /// The web page window. - pub window: Rc, - - /// The web page document. - pub document: Rc, - - /// The canvas rendering context. - /// - /// We keep a reference so that we can easily render things. - pub context: Rc, - - /// The performance object. - pub performance: Rc, } impl Engine { /// Creates a new engine. pub fn new() -> Result { - let window = unwrap!(web_sys::window()); - let document = unwrap!(window.document()); - let performance = unwrap!(window.performance()); - let canvas = unwrap!(document.get_element_by_id("canvas")); - let canvas: web_sys::HtmlCanvasElement = canvas.dyn_into::()?; + let inner = Rc::new(RefCell::new(InnerEngine::new()?)); - canvas.set_width(1920); - canvas.set_height(1080); + // let clone = inner.clone(); + // let cb = Closure::::new(move |event: web_sys::GamepadEvent| { + // let mut inner = clone.borrow_mut(); + // inner.add_gamepad(&event); + // }); - let context = - unwrap!(canvas.get_context("2d")?).dyn_into::()?; + // (*window) + // .add_event_listener_with_callback("gamepadconnected", cb.as_ref().unchecked_ref())?; - let map = Map::from_str(include_str!("../../static/levels/level1.lvl")).unwrap(); - let mut scene = Scene::from_map(map); + // cb.forget(); - let character = Character::new(); - scene.add(character); - - let inner = InnerEngine::new(&document, &performance, scene)?; - - let inner = Rc::new(RefCell::new(inner)); - let window = Rc::new(window); - let document = Rc::new(document); - let performance = Rc::new(performance); - let context = Rc::new(context); - - let clone = inner.clone(); - let cb = Closure::::new(move |event: web_sys::GamepadEvent| { - let mut inner = clone.borrow_mut(); - inner.add_gamepad(&event); - }); - - (*window) - .add_event_listener_with_callback("gamepadconnected", cb.as_ref().unchecked_ref())?; - - cb.forget(); - - Ok(Engine { - inner, - window, - document, - performance, - context, - }) + Ok(Engine { inner }) } /// Starts the engine. @@ -119,7 +75,10 @@ impl Engine { } }); - (*self.window).request_animation_frame(cb.as_ref().unchecked_ref())?; + let inner = self.inner.borrow_mut(); + inner + .window + .request_animation_frame(cb.as_ref().unchecked_ref())?; cb.forget(); @@ -128,11 +87,13 @@ impl Engine { /// Launches a loop of the engine, and schedules the next one. pub fn run(&self) -> Result<()> { + let mut inner = self.inner.borrow_mut(); + // Perform update - self.update()?; + inner.update()?; // Perform render - self.render()?; + inner.render()?; // Schedule next render let clone = self.clone(); @@ -142,94 +103,14 @@ impl Engine { } }); - (*self.window).request_animation_frame(cb.as_ref().unchecked_ref())?; + inner + .window + .request_animation_frame(cb.as_ref().unchecked_ref())?; cb.forget(); Ok(()) } - - /// Triggers the update of the model of the engine. - pub fn update(&self) -> Result<()> { - let mut inner = self.inner.borrow_mut(); - - // Manage the physics - let now = now(&self.performance); - let duration = unwrap!(now.duration_since(inner.after_loop).ok()); - inner.after_loop = now; - - if self.document.has_focus()? { - // Manage events - // while let Some(event) = inner.keyboard.pop() { - // inner.scene.manage_action(&action); - // } - - // let keyboard = inner.keyboard.clone(); - // if inner.scene.update(now, duration) == State::Finished { - // let map = Map::from_str(include_str!("../../static/levels/level1.lvl")).unwrap(); - // let mut scene = Scene::from_map(map); - - // let character = Character::with_controls(Controls::default_keyboard()); - // scene.add(character); - - // inner.scene = scene; - // } - } - - Ok(()) - } - - /// Draw a drawable. - pub fn draw(&self, drawable: &D, view: Bbox) -> Result<()> { - let inner = self.inner.borrow(); - let image = inner.textures.get(drawable.texture()); - - let source = drawable.texture_rect(inner.after_loop); - let mut dest = source.clone(); - dest.position = drawable.position() - view.position; - dest.position.x *= 1920.0 / view.size.x; - dest.position.y *= 1080.0 / view.size.y; - dest.size.x *= 1920.0 / view.size.x; - dest.size.y *= 1080.0 / view.size.y; - - image.render(source, dest, &self.context)?; - Ok(()) - } - - /// Performs the rendering of the engine. - pub fn render(&self) -> Result<()> { - let inner = self.inner.borrow(); - let view = inner.scene.view().unwrap(); // TODO remove this unwrap - - // Clear render - self.context.clear_rect(0.0, 0.0, 1920.0, 1080.0); - self.context - .set_fill_style(&JsValue::from_str("rgb(135, 206, 235)")); - self.context.fill_rect(0.0, 0.0, 1920.0, 1080.0); - - // Draw the scene - let map = inner.scene.map(); - let rows = map.rows(); - let cols = map.cols(); - - for i in 0..rows { - for j in 0..cols { - let tile = map.at(i, j); - if tile.graphic.is_visible() { - self.draw(&tile, view)?; - } - } - } - - // Draw characters - for c in inner.scene.characters() { - if true { - self.draw(c, view)?; - } - } - - Ok(()) - } } /// The data contained in our engine. @@ -245,31 +126,131 @@ pub struct InnerEngine { /// The input manager. pub inputs: InputManager, + + /// The web page window. + pub window: web_sys::Window, + + /// The web page document. + pub document: web_sys::Document, + + /// The canvas rendering context. + /// + /// We keep a reference so that we can easily render things. + pub context: web_sys::CanvasRenderingContext2d, + + /// The performance object. + pub performance: web_sys::Performance, } impl InnerEngine { /// Initializes the engine. - pub fn new( - document: &web_sys::Document, - performance: &web_sys::Performance, - scene: Scene, - ) -> Result { + pub fn new() -> Result { + let window = unwrap!(web_sys::window()); + let document = unwrap!(window.document()); + let performance = unwrap!(window.performance()); + let canvas = unwrap!(document.get_element_by_id("canvas")); + let canvas: web_sys::HtmlCanvasElement = canvas.dyn_into::()?; + + canvas.set_width(1920); + canvas.set_height(1080); + + let context = + unwrap!(canvas.get_context("2d")?).dyn_into::()?; + + let map = Map::from_str(include_str!("../../static/levels/level1.lvl")).unwrap(); + let mut scene = Scene::from_map(map); + + let character = Character::new(); + scene.add(character); + Ok(InnerEngine { scene, after_loop: now(&performance), textures: TextureManager::new()?, inputs: InputManager::new(), + window, + document, + context, + performance, }) } - /// Adds a gamepad. - pub fn add_gamepad(&mut self, gamepad: &web_sys::GamepadEvent) { - // let gamepad = GamepadMap::from_gamepad(gamepad.gamepad().unwrap()); - // let clone = gamepad.clone(); - // self.gamepads.push(clone); + /// Triggers the update of the model of the engine. + pub fn update(&mut self) -> Result<()> { + // Manage the physics + let now = now(&self.performance); + let duration = unwrap!(now.duration_since(self.after_loop).ok()); + self.after_loop = now; - // let controlable = self.scene.controlable_mut().unwrap(); - // controlable.set_controls(Some(Controls::Gamepad(gamepad))); + if self.document.has_focus()? { + // Manage events + // while let Some(event) = inner.keyboard.pop() { + // inner.scene.manage_action(&action); + // } + + // let keyboard = inner.keyboard.clone(); + if self.scene.update(now, duration) == State::Finished { + let map = Map::from_str(include_str!("../../static/levels/level1.lvl")).unwrap(); + let mut scene = Scene::from_map(map); + + let character = Character::new(); + scene.add(character); + + self.scene = scene; + } + } + + Ok(()) + } + + /// Performs the rendering of the engine. + pub fn render(&self) -> Result<()> { + let view = self.scene.view().unwrap(); // TODO remove this unwrap + + // Clear render + self.context.clear_rect(0.0, 0.0, 1920.0, 1080.0); + self.context + .set_fill_style(&JsValue::from_str("rgb(135, 206, 235)")); + self.context.fill_rect(0.0, 0.0, 1920.0, 1080.0); + + // Draw the scene + let map = self.scene.map(); + let rows = map.rows(); + let cols = map.cols(); + + for i in 0..rows { + for j in 0..cols { + let tile = map.at(i, j); + if tile.graphic.is_visible() { + self.draw(&tile, view)?; + } + } + } + + // Draw characters + for c in self.scene.characters() { + if true { + self.draw(c, view)?; + } + } + + Ok(()) + } + + /// Draw a drawable. + pub fn draw(&self, drawable: &D, view: Bbox) -> Result<()> { + let image = self.textures.get(drawable.texture()); + + let source = drawable.texture_rect(self.after_loop); + let mut dest = source.clone(); + dest.position = drawable.position() - view.position; + dest.position.x *= 1920.0 / view.size.x; + dest.position.y *= 1080.0 / view.size.y; + dest.size.x *= 1920.0 / view.size.x; + dest.size.y *= 1080.0 / view.size.y; + + image.render(source, dest, &self.context)?; + Ok(()) } } diff --git a/src/engine/scene.rs b/src/engine/scene.rs index 7cae88f..dd81cd5 100644 --- a/src/engine/scene.rs +++ b/src/engine/scene.rs @@ -47,6 +47,9 @@ impl Scene { /// Returns the controlable. fn controlable(&self) -> Option<&Character> { + // TODO fix this + return Some(&self.characters[0]); + for character in &self.characters { if character.controls().is_some() { return Some(&character);