Begin work on player control

This commit is contained in:
Alex Bethel 2022-01-02 14:30:37 -06:00
parent 54b9f2778c
commit 42dc9a8625
3 changed files with 53 additions and 9 deletions

View file

@ -16,8 +16,24 @@ pub struct CharRender {
pub glyph: char, pub glyph: char,
} }
/// Entities that the user can control using the keyboard.
#[derive(Component)]
pub struct Player;
/// Entities that take turns periodically.
#[derive(Component)]
pub struct TurnTaker {
/// Amount of time from now until the next scheduled turn.
pub next: u32,
/// Amount of time between turns.
pub maximum: u32,
}
/// Registers every existing component with the given ECS world. /// Registers every existing component with the given ECS world.
pub fn register_all(world: &mut World) { pub fn register_all(world: &mut World) {
world.register::<Position>(); world.register::<Position>();
world.register::<CharRender>(); world.register::<CharRender>();
world.register::<Player>();
world.register::<TurnTaker>();
} }

View file

@ -1,8 +1,8 @@
use components::{register_all, CharRender, Position}; use components::{register_all, CharRender, Player, Position, TurnTaker};
use game::{BranchConfig, DungeonLevel}; use game::{BranchConfig, DungeonLevel};
use specs::prelude::*; use specs::prelude::*;
use systems::IOSystem; use systems::{IOSystem, TurnTickSystem};
mod components; mod components;
mod game; mod game;
@ -24,10 +24,16 @@ fn main() {
.create_entity() .create_entity()
.with(Position { x: 5, y: 6 }) .with(Position { x: 5, y: 6 })
.with(CharRender { glyph: '@' }) .with(CharRender { glyph: '@' })
.with(Player)
.with(TurnTaker {
next: 0,
maximum: 10,
})
.build(); .build();
let mut dispatcher = DispatcherBuilder::new() let mut dispatcher = DispatcherBuilder::new()
.with(IOSystem::new(), "render_system", &[]) .with(TurnTickSystem, "turn_tick", &[])
.with(IOSystem::new(), "render", &["turn_tick"])
.build(); .build();
loop { loop {

View file

@ -7,7 +7,7 @@ use pancurses::{endwin, initscr, Window};
use specs::prelude::*; use specs::prelude::*;
use crate::{ use crate::{
components::{CharRender, Position}, components::{CharRender, Player, Position, TurnTaker},
game::DungeonLevel, game::DungeonLevel,
}; };
@ -51,9 +51,13 @@ impl<'a> System<'a> for IOSystem {
ReadExpect<'a, DungeonLevel>, ReadExpect<'a, DungeonLevel>,
ReadStorage<'a, CharRender>, ReadStorage<'a, CharRender>,
ReadStorage<'a, Position>, ReadStorage<'a, Position>,
ReadStorage<'a, Player>,
ReadStorage<'a, TurnTaker>,
); );
fn run(&mut self, (level, renderables, positions): Self::SystemData) { fn run(&mut self, (level, renderables, positions, players, turns): Self::SystemData) {
self.window.clear();
// Draw the base level. // Draw the base level.
level.draw(&self.window); level.draw(&self.window);
@ -64,10 +68,28 @@ impl<'a> System<'a> for IOSystem {
// Leave the cursor at the lower-left. // Leave the cursor at the lower-left.
self.window.mv(0, 0); self.window.mv(0, 0);
self.window.refresh();
// For now, just get a character to avoid redrawing over and // On the player's turn, read input.
// over. for (_player, turn) in (&players, &turns).join() {
if turn.next == 0 {
self.window.refresh();
self.window.getch(); self.window.getch();
} }
} }
}
}
/// System for ticking the turn counter on every entity; this system
/// implements the relationship between real-world time and in-game
/// time.
pub struct TurnTickSystem;
impl<'a> System<'a> for TurnTickSystem {
type SystemData = WriteStorage<'a, TurnTaker>;
fn run(&mut self, mut turn_takers: Self::SystemData) {
for ent in (&mut turn_takers).join() {
ent.next = ent.next.checked_sub(1).unwrap_or(ent.maximum);
}
}
}