library

Online co-op book organization video game
git clone https://git.bradleygannon.com/library.git
Log | Files | Refs

input.rs (4919B)


      1 use std::{collections::HashMap, time::Duration};
      2 
      3 use common::game::{
      4     ActionKind, Player,
      5     book::{Bookshelf, BookshelfId, FloorBook, Slot, SlotAddress},
      6     state::GameState,
      7 };
      8 use macroquad::prelude::*;
      9 
     10 use crate::render::Camera;
     11 
     12 pub(crate) fn handle_movement_input(local_player: &Player, dt: &Duration) -> Option<ActionKind> {
     13     let velocity_x = if is_key_down(KeyCode::A) || is_key_down(KeyCode::Left) {
     14         -GameState::MAX_PLAYER_SPEED_PX_S
     15     } else if is_key_down(KeyCode::D) || is_key_down(KeyCode::Right) {
     16         GameState::MAX_PLAYER_SPEED_PX_S
     17     } else {
     18         0.
     19     };
     20     let velocity_y = if is_key_down(KeyCode::W) || is_key_down(KeyCode::Up) {
     21         -GameState::MAX_PLAYER_SPEED_PX_S
     22     } else if is_key_down(KeyCode::S) || is_key_down(KeyCode::Down) {
     23         GameState::MAX_PLAYER_SPEED_PX_S
     24     } else {
     25         0.
     26     };
     27     if velocity_x != 0. || velocity_y != 0. {
     28         Some(ActionKind::Move {
     29             new_position: local_player.position()
     30                 + Vec2::new(velocity_x, velocity_y) * dt.as_secs_f32(),
     31         })
     32     } else {
     33         None
     34     }
     35 }
     36 
     37 pub(crate) fn handle_pick_up_book_input(
     38     local_player: &Player,
     39     camera: &Camera,
     40     floor_books: &[FloorBook],
     41 ) -> Option<ActionKind> {
     42     if is_mouse_button_pressed(MouseButton::Left)
     43         && let Some(moused_floor_book) = floor_books.iter().find(|fb| {
     44             fb.collider()
     45                 .rect()
     46                 .offset(fb.position())
     47                 .offset(-camera.position())
     48                 .contains({
     49                     let (x, y) = mouse_position();
     50                     Vec2::new(x, y)
     51                 })
     52                 && fb.position().distance(local_player.position())
     53                     <= GameState::MAX_PLAYER_ACTION_RADIUS
     54         })
     55     {
     56         return Some(ActionKind::PickUpBook {
     57             book_id: moused_floor_book.id(),
     58         });
     59     }
     60     None
     61 }
     62 
     63 pub(crate) fn handle_drop_book_input(
     64     local_player: &Player,
     65     selected_book_index: usize,
     66 ) -> Option<ActionKind> {
     67     if is_key_pressed(KeyCode::Q)
     68         && let Some(book_id) = local_player.books().get(selected_book_index)
     69     {
     70         Some(ActionKind::DropBook { book_id: *book_id })
     71     } else {
     72         None
     73     }
     74 }
     75 
     76 pub(crate) fn get_bookshelf_mouse_address(
     77     camera: &Camera,
     78     bookshelves: &HashMap<BookshelfId, Bookshelf>,
     79 ) -> Option<SlotAddress> {
     80     let (mouse_x, mouse_y) = mouse_position();
     81     let mouse = Vec2::new(mouse_x, mouse_y);
     82     for (bookshelf_id, bookshelf) in bookshelves {
     83         let bookshelf_collider = bookshelf.rect().offset(-camera.position());
     84         if bookshelf_collider.contains(mouse) {
     85             let shelf_index = bookshelf.shelf_count()
     86                 - ((mouse.y - bookshelf_collider.y - Bookshelf::FRAME_THICKNESS)
     87                     / (Bookshelf::BOOK_HEIGHT + Bookshelf::SHELF_THICKNESS))
     88                     as usize
     89                 - 1;
     90             let position = ((mouse.x - bookshelf_collider.x - Bookshelf::FRAME_THICKNESS)
     91                 / Bookshelf::BOOK_WIDTH) as usize;
     92             return Some(SlotAddress::new(*bookshelf_id, shelf_index, position));
     93         }
     94     }
     95     None
     96 }
     97 
     98 pub(crate) fn handle_put_book_on_shelf_input(
     99     bookshelves: &HashMap<BookshelfId, Bookshelf>,
    100     camera: &Camera,
    101     local_player: &Player,
    102     selected_book_index: usize,
    103 ) -> Option<ActionKind> {
    104     if is_mouse_button_pressed(MouseButton::Left)
    105         && let Some(slot_address) = get_bookshelf_mouse_address(camera, bookshelves)
    106         && let Some(book_id) = local_player.books().get(selected_book_index)
    107         && let Some(shelf) = bookshelves.get(&slot_address.bookshelf_id())
    108         && let Some(Slot::Empty) = shelf.get_slot(&slot_address)
    109         // TODO Base this on the position of the slot, not the click
    110         && local_player.position().distance({
    111             let (x, y) = mouse_position();
    112             Vec2::new(x, y) + camera.position()
    113         }) <= GameState::MAX_PLAYER_ACTION_RADIUS
    114     {
    115         return Some(ActionKind::PutBookOnShelf {
    116             book_id: *book_id,
    117             slot_address,
    118         });
    119     }
    120     None
    121 }
    122 
    123 pub(crate) fn handle_take_book_off_shelf_input(
    124     bookshelves: &HashMap<BookshelfId, Bookshelf>,
    125     camera: &Camera,
    126     local_player: &Player,
    127 ) -> Option<ActionKind> {
    128     if is_mouse_button_pressed(MouseButton::Left)
    129         && let Some(slot_address) = get_bookshelf_mouse_address(camera, bookshelves)
    130         && let Some(shelf) = bookshelves.get(&slot_address.bookshelf_id())
    131         && let Some(Slot::Book { .. }) = shelf.get_slot(&slot_address)
    132         // TODO Base this on the position of the slot, not the click
    133         && local_player.position().distance({
    134             let (x, y) = mouse_position();
    135             Vec2::new(x, y) + camera.position()
    136         }) <= GameState::MAX_PLAYER_ACTION_RADIUS
    137     {
    138         return Some(ActionKind::TakeBookOffShelf { slot_address });
    139     }
    140     None
    141 }