Browse Source

Add a low-level event abstraction

Getty Ritter 4 years ago
parent
commit
7a810ef9ab
2 changed files with 44 additions and 16 deletions
  1. 1 0
      chapter-07-damage/src/map.rs
  2. 43 16
      chapter-07-damage/src/player.rs

+ 1 - 0
chapter-07-damage/src/map.rs

@@ -195,6 +195,7 @@ impl Algorithm2D for Map {
     }
 }
 
+
 pub fn draw_map(ecs: &World, ctx: &mut Rltk) {
     let map = ecs.fetch::<Map>();
 

+ 43 - 16
chapter-07-damage/src/player.rs

@@ -5,6 +5,7 @@ use super::{CombatStats, Map, Player, Position, RunState, State, Viewshed, Wants
 use specs::prelude::*;
 use std::cmp::{max, min};
 
+
 pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
     let mut positions = ecs.write_storage::<Position>();
     let players = ecs.read_storage::<Player>();
@@ -46,35 +47,61 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) {
     }
 }
 
+/// This type represents all the "low-level" actions we have available
+/// to us, corresponding directly to the set of actions we have bound
+/// on the keys
+enum InputEvent {
+    // attempt to move the player some amount in the given direction
+    // (delta_x and delta_y should be -1, 0, or 1)
+    PlayerMovement {
+        delta_x: i32,
+        delta_y: i32,
+    },
+    // quit the game
+    QuitGame,
+    // do not take any action at all
+    NoAction,
+}
+
+impl Default for InputEvent {
+    // the default for an InputEvent is of course NoAction
+    fn default() -> InputEvent {
+        InputEvent::NoAction
+    }
+}
+
 pub fn player_input(gs: &mut State, ctx: &mut Rltk) -> RunState {
     // Player movement
     match ctx.key {
         None => return RunState::AwaitingInput, // Nothing happened
         Some(key) => match key {
-            VirtualKeyCode::Left | VirtualKeyCode::Numpad4 | VirtualKeyCode::H => {
-                try_move_player(-1, 0, &mut gs.ecs)
-            }
+            VirtualKeyCode::Left | VirtualKeyCode::Numpad4 | VirtualKeyCode::H =>
+                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: -1, delta_y: 0 }),
 
-            VirtualKeyCode::Right | VirtualKeyCode::Numpad6 | VirtualKeyCode::L => {
-                try_move_player(1, 0, &mut gs.ecs)
-            }
+            VirtualKeyCode::Right | VirtualKeyCode::Numpad6 | VirtualKeyCode::L =>
+                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: 1, delta_y: 0 }),
 
-            VirtualKeyCode::Up | VirtualKeyCode::Numpad8 | VirtualKeyCode::K => {
-                try_move_player(0, -1, &mut gs.ecs)
-            }
+            VirtualKeyCode::Up | VirtualKeyCode::Numpad8 | VirtualKeyCode::K =>
+                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: 0, delta_y: -1 }),
 
-            VirtualKeyCode::Down | VirtualKeyCode::Numpad2 | VirtualKeyCode::J => {
-                try_move_player(0, 1, &mut gs.ecs)
-            }
+            VirtualKeyCode::Down | VirtualKeyCode::Numpad2 | VirtualKeyCode::J =>
+                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: 0, delta_y: 1 }),
 
             // Diagonals
-            VirtualKeyCode::Numpad9 | VirtualKeyCode::U => try_move_player(1, -1, &mut gs.ecs),
+            VirtualKeyCode::Numpad9 | VirtualKeyCode::U =>
+                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: 1, delta_y: -1 }),
+
+            VirtualKeyCode::Numpad7 | VirtualKeyCode::Y =>
+                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: -1, delta_y: -1 }),
 
-            VirtualKeyCode::Numpad7 | VirtualKeyCode::Y => try_move_player(-1, -1, &mut gs.ecs),
+            VirtualKeyCode::Numpad3 | VirtualKeyCode::N =>
+                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: 1, delta_y: 1 }),
 
-            VirtualKeyCode::Numpad3 | VirtualKeyCode::N => try_move_player(1, 1, &mut gs.ecs),
+            VirtualKeyCode::Numpad1 | VirtualKeyCode::B =>
+                gs.ecs.insert(InputEvent::PlayerMovement { delta_x: -1, delta_y: 1 }),
 
-            VirtualKeyCode::Numpad1 | VirtualKeyCode::B => try_move_player(-1, 1, &mut gs.ecs),
+            VirtualKeyCode::Q | VirtualKeyCode::Escape =>
+                gs.ecs.insert(InputEvent::QuitGame),
 
             _ => return RunState::AwaitingInput,
         },