library

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

mod.rs (3909B)


      1 use std::{
      2     collections::VecDeque,
      3     sync::mpsc::{Receiver, Sender},
      4     time::{Duration, Instant, SystemTime},
      5 };
      6 
      7 use crate::render::Camera;
      8 use common::game::{Action, ActionKind, Player, Response, book::FloorBook, state::GameState};
      9 use macroquad::prelude::*;
     10 use serde::{Deserialize, Serialize};
     11 use uuid::Uuid;
     12 
     13 mod run;
     14 mod state;
     15 
     16 const CONFY_APP_NAME: &str = "library-game";
     17 const CONFY_CONFIG_NAME: &str = "config";
     18 
     19 #[derive(Debug)]
     20 pub(crate) struct ClientState {
     21     mode: ViewMode,
     22     camera: Camera,
     23     game: GameState,
     24     old_game: GameState,
     25     local_player_id: Option<Uuid>,
     26     sequence_number: u32,
     27     unresponded_actions: VecDeque<Action>,
     28     interpolation_basis: SystemTime,
     29     debug_view: bool,
     30     t0: Instant,
     31     t1: Instant,
     32     dt: Duration,
     33     tx: Option<Sender<Action>>,
     34     rx: Option<Receiver<Response>>,
     35     config: Config,
     36     menu_error: String,
     37     first_frame: bool,
     38     selected_book: usize,
     39 }
     40 
     41 impl Default for ClientState {
     42     fn default() -> Self {
     43         Self {
     44             mode: ViewMode::default(),
     45             camera: Camera::default(),
     46             game: GameState::default(),
     47             old_game: GameState::default(),
     48             local_player_id: None,
     49             sequence_number: 0,
     50             unresponded_actions: VecDeque::new(),
     51             interpolation_basis: SystemTime::now(),
     52             debug_view: cfg!(debug_assertions),
     53             t0: Instant::now(),
     54             t1: Instant::now(),
     55             dt: Duration::ZERO,
     56             tx: None,
     57             rx: None,
     58             config: confy::load(CONFY_APP_NAME, Some(CONFY_CONFIG_NAME)).unwrap_or_default(),
     59             menu_error: String::new(),
     60             first_frame: true,
     61             selected_book: 0,
     62         }
     63     }
     64 }
     65 
     66 pub(crate) fn handle_movement_input(local_player: &Player, dt: &Duration) -> Option<ActionKind> {
     67     let velocity_x = if is_key_down(KeyCode::A) || is_key_down(KeyCode::Left) {
     68         -GameState::MAX_PLAYER_SPEED_PX_S
     69     } else if is_key_down(KeyCode::D) || is_key_down(KeyCode::Right) {
     70         GameState::MAX_PLAYER_SPEED_PX_S
     71     } else {
     72         0.
     73     };
     74     let velocity_y = if is_key_down(KeyCode::W) || is_key_down(KeyCode::Up) {
     75         -GameState::MAX_PLAYER_SPEED_PX_S
     76     } else if is_key_down(KeyCode::S) || is_key_down(KeyCode::Down) {
     77         GameState::MAX_PLAYER_SPEED_PX_S
     78     } else {
     79         0.
     80     };
     81     if velocity_x != 0. || velocity_y != 0. {
     82         Some(ActionKind::Move {
     83             new_position: local_player.position()
     84                 + Vec2::new(velocity_x, velocity_y) * dt.as_secs_f32(),
     85         })
     86     } else {
     87         None
     88     }
     89 }
     90 
     91 pub(crate) fn handle_pick_up_book_input(
     92     local_player: &Player,
     93     floor_books: &[FloorBook],
     94 ) -> Option<ActionKind> {
     95     if is_key_pressed(KeyCode::Space) {
     96         let local_player_collider = local_player
     97             .collider()
     98             .rect()
     99             .offset(local_player.position());
    100         if let Some(floor_book) = floor_books.iter().find(|fb| {
    101             fb.collider()
    102                 .rect()
    103                 .offset(fb.position())
    104                 .overlaps(&local_player_collider)
    105         }) {
    106             return Some(ActionKind::PickUpBook {
    107                 book_id: floor_book.id(),
    108             });
    109         }
    110     }
    111     None
    112 }
    113 
    114 pub(crate) fn handle_drop_book_input(
    115     local_player: &Player,
    116     selected_book_index: usize,
    117 ) -> Option<ActionKind> {
    118     if is_key_pressed(KeyCode::Q)
    119         && let Some(book_id) = local_player.books().get(selected_book_index)
    120     {
    121         Some(ActionKind::DropBook { book_id: *book_id })
    122     } else {
    123         None
    124     }
    125 }
    126 
    127 #[derive(Clone, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
    128 struct Config {
    129     player_name: String,
    130     server: String,
    131 }
    132 
    133 #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
    134 pub(crate) enum ViewMode {
    135     #[default]
    136     Menu,
    137     Game,
    138 }