diff options
-rw-r--r-- | games/rstnode/rst-client/src/graphics/mod.rs | 4 | ||||
-rw-r--r-- | games/rstnode/rst-client/src/graphics/vector2.rs | 82 | ||||
-rw-r--r-- | games/rstnode/rst-client/src/input.rs | 23 | ||||
-rw-r--r-- | games/rstnode/rst-client/src/main.rs | 9 | ||||
-rw-r--r-- | games/rstnode/rst-client/src/state.rs | 16 | ||||
-rw-r--r-- | games/rstnode/rst-client/src/viewport.rs | 63 |
6 files changed, 187 insertions, 10 deletions
diff --git a/games/rstnode/rst-client/src/graphics/mod.rs b/games/rstnode/rst-client/src/graphics/mod.rs index 095e66f1ad1f..a7ba676ecc6b 100644 --- a/games/rstnode/rst-client/src/graphics/mod.rs +++ b/games/rstnode/rst-client/src/graphics/mod.rs @@ -8,8 +8,12 @@ pub mod entities; pub mod ui; +mod vector2; +pub use vector2::*; + use crate::state::ClientState; use ggez::{Context, GameResult}; +use std::ops::{Add, Mul, Sub}; /// A utility module to include everything required to implement a /// graphics entity diff --git a/games/rstnode/rst-client/src/graphics/vector2.rs b/games/rstnode/rst-client/src/graphics/vector2.rs new file mode 100644 index 000000000000..5204e77fa443 --- /dev/null +++ b/games/rstnode/rst-client/src/graphics/vector2.rs @@ -0,0 +1,82 @@ +use std::fmt::{self, Display, Formatter}; +use std::ops::{Add, Mul, Sub, SubAssign}; + +/// Just a vector +#[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd)] +pub struct Vector2 { + pub x: f32, + pub y: f32, +} + +impl Display for Vector2 { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "[{}, {}]", self.x, self.y) + } +} + +impl Vector2 { + pub fn new(x: f32, y: f32) -> Self { + Self { x, y } + } + + pub fn abs(self) -> Self { + Self { + x: self.x.abs(), + y: self.y.abs(), + } + } +} + +impl Sub for Vector2 { + type Output = Vector2; + + fn sub(self, o: Vector2) -> Self::Output { + Vector2 { + x: self.x - o.x, + y: self.y - o.y, + } + } +} + +impl SubAssign for Vector2 { + fn sub_assign(&mut self, o: Self) { + *self = Self { + x: self.x - o.x, + y: self.y - o.y, + } + } +} + +impl Add for Vector2 { + type Output = Vector2; + + fn add(self, o: Vector2) -> Self::Output { + Vector2 { + x: self.x + o.x, + y: self.y + o.y, + } + } +} + +impl Mul for Vector2 { + type Output = Vector2; + + fn mul(self, o: Vector2) -> Self::Output { + Vector2 { + x: self.x * o.x, + y: self.y * o.y, + } + } +} + +impl From<Vector2> for mint::Point2<f32> { + fn from(v: Vector2) -> Self { + [v.x, v.y].into() + } +} + +impl From<mint::Point2<f32>> for Vector2 { + fn from(v: mint::Point2<f32>) -> Self { + Self { x: v.x, y: v.y } + } +} diff --git a/games/rstnode/rst-client/src/input.rs b/games/rstnode/rst-client/src/input.rs index 4e901b8ade06..281386986434 100644 --- a/games/rstnode/rst-client/src/input.rs +++ b/games/rstnode/rst-client/src/input.rs @@ -1,50 +1,55 @@ //! Advanced input handler +use crate::{graphics::Vector2, viewport::Viewport}; use ggez::{ event::EventHandler, input::mouse::{self, MouseButton}, Context, GameResult, }; -use mint::Point2; pub struct InputHandle { /// The mouse position on the viewport - pub mouse_pos: Point2<f32>, + pub mouse_pos: Vector2, /// Whether the left mouse button is pressed this frame pub left_pressed: bool, + /// Whether the middle mouse button is pressed this frame + pub middle_pressed: bool, /// Whether the right mouse button is pressed this frame pub right_pressed: bool, /// Set when pressing left mouse and unset when releasing it - pub drag_point: Option<Point2<f32>>, + pub drag_point: Option<Vector2>, } impl InputHandle { pub fn new() -> Self { Self { - mouse_pos: [0.0, 0.0].into(), + mouse_pos: Vector2::new(0.0, 0.0), left_pressed: false, + middle_pressed: false, right_pressed: false, drag_point: None, } } /// Get the unprojected mouse coordinates - pub fn unproject(&self) -> Point2<f32> { - self.mouse_pos.clone(); + pub fn unproject(&self, vp: &Viewport) -> Vector2 { + // self.mouse_pos.clone() - vp.start().clone() + todo!() } } impl EventHandler for InputHandle { fn update(&mut self, ctx: &mut Context) -> GameResult<()> { - self.mouse_pos = mouse::position(&ctx); + self.mouse_pos = mouse::position(&ctx).into(); self.left_pressed = mouse::button_pressed(ctx, MouseButton::Left); + self.middle_pressed = mouse::button_pressed(ctx, MouseButton::Middle); self.right_pressed = mouse::button_pressed(ctx, MouseButton::Right); // Only set the drag_point once and unset when we release Left button - if self.left_pressed && self.drag_point.is_none() { + if self.middle_pressed && self.drag_point.is_none() { self.drag_point = Some(self.mouse_pos.clone()); - } else if !self.left_pressed { + } else if !self.middle_pressed { self.drag_point = None; } diff --git a/games/rstnode/rst-client/src/main.rs b/games/rstnode/rst-client/src/main.rs index aa86de26c952..a6ba4a59cdc1 100644 --- a/games/rstnode/rst-client/src/main.rs +++ b/games/rstnode/rst-client/src/main.rs @@ -14,6 +14,7 @@ mod input; mod log; mod settings; mod state; +mod viewport; mod window; #[allow(unused)] @@ -36,7 +37,13 @@ fn main() { // Load assets tree let assets = assets::load_tree(window.ctx(), &settings).unwrap_or_else(|e| fatal!("LoadError: {}!", e)); - let state = ClientState::new(settings, assets); + // Create the client state + let mut state = ClientState::new(settings, assets); + + // Initialise the viewport first! + state.viewport().init(window.ctx()); + + // Window goes brrrr window.run(state) } diff --git a/games/rstnode/rst-client/src/state.rs b/games/rstnode/rst-client/src/state.rs index b1b5e89f3d13..d3b5bbcc3d7b 100644 --- a/games/rstnode/rst-client/src/state.rs +++ b/games/rstnode/rst-client/src/state.rs @@ -7,6 +7,7 @@ use crate::{ Renderer, }, input::InputHandle, + viewport::Viewport, GameSettings, }; use ggez::{event::EventHandler, graphics, Context, GameResult}; @@ -17,6 +18,7 @@ pub struct ClientState { assets: Assets, settings: GameSettings, input: InputHandle, + vp: Viewport, // Game state node: NodeRndr, @@ -27,6 +29,7 @@ impl ClientState { Self { assets, settings, + vp: Viewport::new(), input: InputHandle::new(), node: NodeRndr { loc: Coordinates(512.0, 512.0), @@ -49,6 +52,10 @@ impl ClientState { } } + pub fn viewport(&mut self) -> &mut Viewport { + &mut self.vp + } + pub fn assets(&self) -> &Assets { &self.assets } @@ -56,7 +63,16 @@ impl ClientState { impl EventHandler for ClientState { fn update(&mut self, ctx: &mut Context) -> GameResult<()> { + // TODO: get simulation updates + + // Get new input state self.input.update(ctx)?; + + // Apply inputs to viewpoirt + self.vp.apply(ctx, &self.input)?; + + // Update viewport + self.vp.update(ctx)?; Ok(()) } diff --git a/games/rstnode/rst-client/src/viewport.rs b/games/rstnode/rst-client/src/viewport.rs new file mode 100644 index 000000000000..3f9e803e387b --- /dev/null +++ b/games/rstnode/rst-client/src/viewport.rs @@ -0,0 +1,63 @@ +//! Viewport utilities + +use crate::{graphics::Vector2, input::InputHandle}; +use ggez::{ + error::GameResult, + graphics::{self, Rect}, + Context, +}; + +#[derive(Default)] +pub struct Viewport { + start: Vector2, + prev_start: Vector2, + size: Vector2, +} + +impl Viewport { + pub fn new() -> Self { + Self::default() + } + + pub fn start(&self) -> &Vector2 { + &self.start + } + + /// Must be called at least once before calling + /// [`update`](Self::update) + pub fn init(&mut self, ctx: &mut Context) { + let Rect { x, y, w, h } = graphics::screen_coordinates(&ctx); + self.start = Vector2::new(x, y); + self.prev_start = self.start; + self.size = Vector2::new(w, h); + } + + /// Update the game state with the curent viewport data + pub fn update(&self, ctx: &mut Context) -> GameResult<()> { + graphics::set_screen_coordinates( + ctx, + Rect { + x: self.start.x, + y: self.start.y, + w: self.size.x, + h: self.size.y, + }, + )?; + + Ok(()) + } + + /// Apply changes from the input handle to the viewport + pub fn apply(&mut self, _: &mut Context, input: &InputHandle) -> GameResult<()> { + if input.middle_pressed { + let drag = input.drag_point.as_ref().unwrap().clone(); + let pos = input.mouse_pos.clone(); + self.start = self.prev_start + (drag - pos); + debug!("Changing VP start: {}", self.start); + } else { + self.prev_start = self.start; + } + + Ok(()) + } +} |