From cc033efe05f7cc21994cfea3668e87db2bfb9bf8 Mon Sep 17 00:00:00 2001 From: Yash Karandikar Date: Wed, 30 Mar 2022 15:18:53 -0500 Subject: [PATCH] Create wrapper around mouse and keyboard --- src/lib.rs | 71 +++++++++++++++++++++++++++++++++++++++++++---------- src/main.rs | 56 ++++++++++++++++++++---------------------- 2 files changed, 84 insertions(+), 43 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index bb13cec..a7237e3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,7 +59,7 @@ use sdl2::{ surface::Surface, ttf::{FontError, Sdl2TtfContext}, video::{Window, WindowBuildError, WindowContext}, - EventPump, IntegerOrSdlError, + EventPump, IntegerOrSdlError, mouse::MouseButton, keyboard::Scancode, }; #[doc(no_inline)] @@ -184,7 +184,7 @@ impl Sprite { /// # }); /// ``` pub fn draw(&mut self, ctx: &mut Context) -> Result<()> { - let (creator, canvas) = ctx.inner(); + let (creator, canvas, _) = ctx.inner(); let text = creator.create_texture_from_surface(&self.surf)?; canvas.copy_ex(&text, None, self.rect, self.angle, None, false, false)?; @@ -411,15 +411,17 @@ impl DerefMut for SpriteCollection { /// In most cases, this should never actually be used; instead, just pass it around to the various cat-box functions such as [`Sprite::draw()`]. pub struct Context { canvas: Canvas, + event_pump: EventPump, texture_creator: TextureCreator, ttf_subsystem: Sdl2TtfContext, } impl Context { - fn new(canvas: Canvas, ttf_subsystem: Sdl2TtfContext) -> Self { + fn new(canvas: Canvas, pump: EventPump, ttf_subsystem: Sdl2TtfContext) -> Self { let creator = canvas.texture_creator(); Self { canvas, + event_pump: pump, texture_creator: creator, ttf_subsystem, } @@ -428,8 +430,8 @@ impl Context { /// Get the inner [`Canvas`](sdl2::render::Canvas) and [`TextureCreator`](sdl2::render::TextureCreator). /// /// Only use this method if you know what you're doing. - pub fn inner(&mut self) -> (&TextureCreator, &mut Canvas) { - (&self.texture_creator, &mut self.canvas) + pub fn inner(&mut self) -> (&TextureCreator, &mut Canvas, &mut EventPump) { + (&self.texture_creator, &mut self.canvas, &mut self.event_pump) } fn update(&mut self) { @@ -440,6 +442,18 @@ impl Context { self.canvas.clear(); } + fn check_for_quit(&mut self) -> bool { + let (_, _, pump) = self.inner(); + + for event in pump.poll_iter() { + if let Event::Quit { .. } = event { + return true; + } + } + + false + } + /// Set the background colour. See [`Canvas::set_draw_color()`](sdl2::render::Canvas::set_draw_color()) for more info. pub fn set_background_colour(&mut self, r: u8, g: u8, b: u8) { self.canvas.set_draw_color(Color::RGB(r, g, b)); @@ -497,7 +511,7 @@ pub fn draw_text>( }?; drop(font); - let (creator, canvas) = ctx.inner(); + let (creator, canvas, _) = ctx.inner(); let texture = creator.create_texture_from_surface(&surf)?; let srect = surf.rect(); @@ -508,6 +522,39 @@ pub fn draw_text>( Ok(()) } +#[derive(Debug)] +pub struct MouseRepr { + pub buttons: Vec, + pub x: i32, + pub y: i32 +} + +pub struct KeyboardRepr { + pub keys: Vec +} + +pub fn get_mouse_state(ctx: &mut Context) -> MouseRepr { + let (_, _, pump) = ctx.inner(); + + let mouse = pump.mouse_state(); + + MouseRepr { + buttons: mouse.pressed_mouse_buttons().collect(), + x: mouse.x(), + y: mouse.y(), + } +} + +pub fn get_keyboard_state(ctx: &mut Context) -> KeyboardRepr { + let (_, _, pump) = ctx.inner(); + + let keyboard = pump.keyboard_state(); + + KeyboardRepr { + keys: keyboard.pressed_scancodes().collect() + } +} + /// Representation of the game. pub struct Game { /// The title that the window displays. @@ -547,7 +594,7 @@ impl Game { /// // Game logic goes here /// }); /// ``` - pub fn run(&self, mut func: F) -> Result<()> { + pub fn run(&self, mut func: F) -> Result<()> { let sdl_context = sdl2::init()?; let video_subsystem = sdl_context.video()?; @@ -562,17 +609,15 @@ impl Game { let s = sdl2::ttf::init().unwrap(); let event_pump = sdl_context.event_pump()?; - - let mut events = Events { pump: event_pump }; - - let mut ctx = Context::new(canvas, s); + + let mut ctx = Context::new(canvas, event_pump, s); loop { - if self.stopped.get() { + if self.stopped.get() || ctx.check_for_quit() { break; } ctx.clear(); - func(&mut ctx, &mut events); + func(&mut ctx); ctx.update(); } diff --git a/src/main.rs b/src/main.rs index 0d7a8ac..fc3bf2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ -use cat_box::{draw_text, Event, Game, Keycode, Sprite, SpriteCollection}; +use cat_box::{draw_text, Game, Sprite, SpriteCollection, get_mouse_state, get_keyboard_state}; +use sdl2::keyboard::Scancode; fn main() { let game = Game::new("catbox demo", 1000, 800); @@ -14,7 +15,7 @@ fn main() { coll.push(x); } } - game.run(|ctx, event_pump| { + game.run(|ctx| { i = (i + 1) % 255; ctx.set_background_colour(i as u8, 64, 255); @@ -32,47 +33,42 @@ fn main() { .unwrap(); let (start_x, start_y) = s.position(); - let m = sdl2::mouse::MouseState::new(event_pump.as_ref()); - let x_diff = m.x() - start_x; - let y_diff = m.y() - start_y; + let m = get_mouse_state(ctx); + let x_diff = m.x - start_x; + let y_diff = m.y - start_y; let angle = (y_diff as f64).atan2(x_diff as f64); s.set_angle(angle.to_degrees()); for spr in coll.iter() { let (start_x, start_y) = spr.position(); - let m = sdl2::mouse::MouseState::new(event_pump.as_ref()); - let x_diff = m.x() - start_x; - let y_diff = m.y() - start_y; + let m = get_mouse_state(ctx); + let x_diff = m.x - start_x; + let y_diff = m.y - start_y; let angle = (y_diff as f64).atan2(x_diff as f64); spr.set_angle(angle.to_degrees()); } - for event in event_pump { - match event { - Event::Quit { .. } - | Event::KeyDown { - keycode: Some(Keycode::Escape), - .. - } => game.terminate(), + let keys = get_keyboard_state(ctx).keys; - Event::KeyDown { keycode, .. } => { - let offset = match keycode.unwrap() { - Keycode::W | Keycode::Up => (0, 5), - Keycode::S | Keycode::Down => (0, -5), - Keycode::A | Keycode::Left => (-5, 0), - Keycode::D | Keycode::Right => (5, 0), - _ => (0, 0), - }; + for key in keys { + let offset = match key { + Scancode::Escape => { + game.terminate(); + (0, 0) + }, + Scancode::W | Scancode::Up => (0, 5), + Scancode::S | Scancode::Down => (0, -5), + Scancode::A | Scancode::Left => (-5, 0), + Scancode::D | Scancode::Right => (5, 0), + _ => (0, 0), + }; - s.translate(offset); - - for spr in coll.iter() { - spr.translate(offset); - } - } - _ => {} + s.translate(offset); + + for spr in coll.iter() { + spr.translate(offset); } }