This commit is contained in:
Tyrel Souza 2021-08-28 19:28:48 -04:00
parent 8ab719b569
commit 367d5f26ae
9 changed files with 142 additions and 18 deletions

View File

@ -11,3 +11,12 @@ pub struct Player;
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub struct Enemy; pub struct Enemy;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct MovingRandomly;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct WantsToMove {
pub entity: Entity,
pub destination: Point,
}

View File

@ -4,6 +4,7 @@ mod map;
mod map_builder; mod map_builder;
mod spawners; mod spawners;
mod systems; mod systems;
mod turn_state;
mod prelude { mod prelude {
pub use bracket_lib::prelude::*; pub use bracket_lib::prelude::*;
@ -20,13 +21,16 @@ mod prelude {
pub use crate::map_builder::*; pub use crate::map_builder::*;
pub use crate::spawners::*; pub use crate::spawners::*;
pub use crate::systems::*; pub use crate::systems::*;
pub use crate::turn_state::*;
} }
use prelude::*; use prelude::*;
struct State { struct State {
ecs: World, ecs: World,
resources: Resources, resources: Resources,
systems: Schedule, input_systems: Schedule,
player_systems: Schedule,
monster_systems: Schedule,
} }
impl State { impl State {
fn new() -> Self { fn new() -> Self {
@ -45,10 +49,13 @@ impl State {
resources.insert(map_builder.map); resources.insert(map_builder.map);
resources.insert(Camera::new(map_builder.player_start)); resources.insert(Camera::new(map_builder.player_start));
resources.insert(TurnState::AwaitingInput);
State { State {
ecs, ecs,
resources, resources,
systems: build_scheduler(), input_systems: input_build_scheduler(),
player_systems: player_build_scheduler(),
monster_systems: monster_build_scheduler(),
} }
} }
} }
@ -59,7 +66,19 @@ impl GameState for State {
ctx.set_active_console(1); ctx.set_active_console(1);
ctx.cls(); ctx.cls();
self.resources.insert(ctx.key); self.resources.insert(ctx.key);
self.systems.execute(&mut self.ecs, &mut self.resources); //self.systems.execute(&mut self.ecs, &mut self.resources);
let current_state = self.resources.get::<TurnState>().unwrap().clone();
match current_state {
TurnState::AwaitingInput => self
.input_systems
.execute(&mut self.ecs, &mut self.resources),
TurnState::PlayerTurn => self
.player_systems
.execute(&mut self.ecs, &mut self.resources),
TurnState::MonsterTurn => self
.monster_systems
.execute(&mut self.ecs, &mut self.resources),
}
render_draw_buffer(ctx).expect("Render error"); render_draw_buffer(ctx).expect("Render error");
} }
} }

View File

@ -24,5 +24,6 @@ pub fn spawn_monster(ecs: &mut World, rng: &mut RandomNumberGenerator, pos: Poin
_ => to_cp437('g'), // goblin _ => to_cp437('g'), // goblin
}, },
}, },
MovingRandomly {},
)); ));
} }

11
src/systems/end_turn.rs Normal file
View File

@ -0,0 +1,11 @@
use crate::prelude::*;
#[system]
pub fn end_turn(#[resource] turn_state: &mut TurnState) {
let new_state = match turn_state {
TurnState::AwaitingInput => return,
TurnState::PlayerTurn => TurnState::MonsterTurn,
TurnState::MonsterTurn => TurnState::AwaitingInput,
};
*turn_state = new_state;
}

View File

@ -1,14 +1,41 @@
use crate::prelude::*; use crate::prelude::*;
mod collisions; mod collisions;
mod end_turn;
mod entity_render; mod entity_render;
mod map_render; mod map_render;
mod movement;
mod player_input; mod player_input;
mod random_move;
pub fn build_scheduler() -> Schedule { pub fn input_build_scheduler() -> Schedule {
Schedule::builder() Schedule::builder()
.add_system(player_input::player_input_system()) .add_system(player_input::player_input_system())
.add_system(collisions::collisions_system()) .flush()
.add_system(map_render::map_render_system()) .add_system(map_render::map_render_system())
.add_system(entity_render::entity_render_system()) .add_system(entity_render::entity_render_system())
.build() .build()
} }
pub fn player_build_scheduler() -> Schedule {
Schedule::builder()
.add_system(movement::movement_system())
.flush()
.add_system(collisions::collisions_system())
.flush()
.add_system(map_render::map_render_system())
.add_system(entity_render::entity_render_system())
.add_system(end_turn::end_turn_system())
.build()
}
pub fn monster_build_scheduler() -> Schedule {
Schedule::builder()
.add_system(random_move::random_move_system())
.flush()
.add_system(movement::movement_system())
.flush()
.add_system(collisions::collisions_system())
.flush()
.add_system(map_render::map_render_system())
.add_system(entity_render::entity_render_system())
.add_system(end_turn::end_turn_system())
.build()
}

25
src/systems/movement.rs Normal file
View File

@ -0,0 +1,25 @@
pub use crate::prelude::*;
#[system(for_each)]
#[read_component(Player)]
pub fn movement(
entity: &Entity,
want_move: &WantsToMove,
#[resource] map: &Map,
#[resource] camera: &mut Camera,
ecs: &mut SubWorld,
commands: &mut CommandBuffer,
) {
if map.can_enter_tile(want_move.destination) {
commands.add_component(want_move.entity, want_move.destination);
if ecs
.entry_ref(want_move.entity)
.unwrap()
.get_component::<Player>()
.is_ok()
{
camera.on_player_move(want_move.destination);
}
}
commands.remove(*entity);
}

View File

@ -1,14 +1,15 @@
use crate::prelude::*; use crate::prelude::*;
#[system] #[system]
#[write_component(Point)] #[read_component(Point)]
#[read_component(Player)] #[read_component(Player)]
pub fn player_input( pub fn player_input(
ecs: &mut SubWorld, ecs: &mut SubWorld,
#[resource] map: &Map, commands: &mut CommandBuffer,
#[resource] key: &Option<VirtualKeyCode>, #[resource] key: &Option<VirtualKeyCode>,
#[resource] camera: &mut Camera, #[resource] turn_state: &mut TurnState,
) { ) {
let mut players = <(Entity, &Point)>::query().filter(component::<Player>());
if let Some(key) = key { if let Some(key) = key {
let delta = match key { let delta = match key {
VirtualKeyCode::Left => Point::new(-1, 0), VirtualKeyCode::Left => Point::new(-1, 0),
@ -17,15 +18,16 @@ pub fn player_input(
VirtualKeyCode::Down => Point::new(0, 1), VirtualKeyCode::Down => Point::new(0, 1),
_ => Point::new(0, 0), _ => Point::new(0, 0),
}; };
if delta.x != 0 || delta.y != 0 { players.iter(ecs).for_each(|(entity, pos)| {
let mut players = <&mut Point>::query().filter(component::<Player>());
players.iter_mut(ecs).for_each(|pos| {
let destination = *pos + delta; let destination = *pos + delta;
if map.can_enter_tile(destination) { commands.push((
*pos = destination; (),
camera.on_player_move(destination); WantsToMove {
} entity: *entity,
destination,
},
));
}); });
} *turn_state = TurnState::PlayerTurn;
} }
} }

View File

@ -0,0 +1,24 @@
pub use crate::prelude::*;
#[system]
#[read_component(Point)]
#[read_component(MovingRandomly)]
pub fn random_move(ecs: &mut SubWorld, commands: &mut CommandBuffer) {
let mut movers = <(Entity, &Point, &MovingRandomly)>::query();
movers.iter_mut(ecs).for_each(|(entity, pos, _)| {
let mut rng = RandomNumberGenerator::new();
let destination = match rng.range(0, 4) {
0 => Point::new(-1, 0),
1 => Point::new(1, 0),
2 => Point::new(0, -1),
_ => Point::new(0, 1),
} + *pos;
commands.push((
(),
WantsToMove {
entity: *entity,
destination,
},
));
});
}

6
src/turn_state.rs Normal file
View File

@ -0,0 +1,6 @@
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum TurnState {
AwaitingInput,
PlayerTurn,
MonsterTurn,
}