Skip to content

Commit ce73689

Browse files
feat: add the ability to load a map from a file (#3)
* feat: add the ability to load a map from a file
1 parent a5996b8 commit ce73689

File tree

11 files changed

+436
-84
lines changed

11 files changed

+436
-84
lines changed

.github/workflows/main.yml

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,34 +40,58 @@ jobs:
4040
- name: Build
4141
run: cargo build --verbose
4242
- name: Format Check
43-
run: cargo fmt -- --check --verbose
43+
run: |
44+
cargo fmt --version
45+
cargo fmt -- --check --verbose
4446
- name: Lint Check
45-
run: cargo clippy -p rustybox -- --verbose -D warnings
47+
run: |
48+
cargo clippy --version
49+
cargo clippy -p rustybox -- --verbose -D warnings
4650
- name: Test
4751
run: cargo test --verbose
4852
- name: Build Release
4953
run: cargo build --release --verbose
54+
- name: Move Artifacts (ubuntu)
55+
if: ${{ matrix.build == 'ubuntu' }}
56+
run: cp target/release/rustybox rustybox
57+
- name: Move Artifacts (macos)
58+
if: ${{ matrix.build == 'macos' }}
59+
run: cp target/release/rustybox rustybox
60+
- name: Move Artifacts (win32)
61+
if: ${{ matrix.build == 'win32' }}
62+
run: copy target\release\rustybox.exe rustybox.exe
63+
- name: Move Artifacts (win64)
64+
if: ${{ matrix.build == 'win64' }}
65+
run: copy target\release\rustybox.exe rustybox.exe
5066
- name: Upload Artifact (ubuntu)
5167
if: ${{ matrix.build == 'ubuntu' }}
5268
uses: actions/upload-artifact@v2.2.2
5369
with:
5470
name: rustybox-${{ matrix.build }}
55-
path: target/release/rustybox
71+
path: |
72+
rustybox
73+
assets/**/*
5674
- name: Upload Artifact (macos)
5775
if: ${{ matrix.build == 'macos' }}
5876
uses: actions/upload-artifact@v2.2.2
5977
with:
6078
name: rustybox-${{ matrix.build }}
61-
path: target/release/rustybox
79+
path: |
80+
rustybox
81+
assets/**/*
6282
- name: Upload Artifact (win32)
6383
if: ${{ matrix.build == 'win32' }}
6484
uses: actions/upload-artifact@v2.2.2
6585
with:
6686
name: rustybox-${{ matrix.build }}
67-
path: target\release\rustybox.exe
87+
path: |
88+
rustybox.exe
89+
assets\**\*
6890
- name: Upload Artifact (win64)
6991
if: ${{ matrix.build == 'win64' }}
7092
uses: actions/upload-artifact@v2.2.2
7193
with:
7294
name: rustybox-${{ matrix.build }}
73-
path: target\release\rustybox.exe
95+
path: |
96+
rustybox.exe
97+
assets\**\*

assets/maps/default.txt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
########################################################################################################################
2+
# #
3+
# * #
4+
# #
5+
# #
6+
# #
7+
# #
8+
# #
9+
# #
10+
# |--------| #
11+
# | , | * #
12+
# | | #
13+
# |---+----| #
14+
# #
15+
# #
16+
# #
17+
# #
18+
# #
19+
# |-----------| #
20+
# | | #
21+
# | | #
22+
# | | #
23+
# |-----x-----| #
24+
# #
25+
# #
26+
# #
27+
# * #
28+
# #
29+
# #
30+
########################################################################################################################%

src/engine.rs

Lines changed: 15 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,39 @@
11
use crate::entity::player::Player;
22
use crate::entity::Entity;
33
use crate::viewport::Viewport;
4-
use console_engine::{pixel, ConsoleEngine, KeyCode, KeyModifiers};
4+
use crate::world_map::WorldMap;
5+
use console_engine::{ConsoleEngine, KeyCode, KeyModifiers};
56
use std::collections::HashMap;
6-
use uuid::Uuid;
77

88
pub fn run(width: u32, height: u32, target_fps: u32) {
99
let viewport = Viewport::new(width, height, target_fps);
1010
let mut console =
1111
console_engine::ConsoleEngine::init(viewport.width, viewport.height, viewport.target_fps);
1212
let mut entity_map = HashMap::new();
13+
let world_map = WorldMap::new(String::from("default.txt"));
14+
info!("Initialised default map.");
15+
16+
let current_player_uuid = Player::create_player(&mut entity_map);
17+
info!("Initialised player: {}", &current_player_uuid);
1318

14-
create_player(&mut entity_map);
1519
loop {
1620
console.wait_frame();
1721
console.clear_screen();
18-
draw_viewport_boundary(&mut console, &viewport);
19-
update_entities(&console, &mut entity_map, &viewport);
20-
draw_entities(&mut console, &entity_map);
22+
Entity::update_entities(&console, &mut entity_map, &world_map);
23+
Viewport::draw_viewport_contents(
24+
&mut console,
25+
&entity_map,
26+
&viewport,
27+
&world_map,
28+
&current_player_uuid,
29+
);
2130
if should_quit(&console) {
2231
info!("Ctrl-q detected - quitting app.");
2332
break;
2433
}
2534
}
2635
}
2736

28-
fn create_player(entity_map: &mut HashMap<Uuid, Entity>) {
29-
entity_map.insert(Uuid::new_v4(), Entity::Player(Player::new()));
30-
}
31-
32-
fn update_entities(
33-
console: &ConsoleEngine,
34-
entity_map: &mut HashMap<Uuid, Entity>,
35-
viewport: &Viewport,
36-
) {
37-
for entity in entity_map.values_mut() {
38-
match entity {
39-
Entity::Player(ref mut player) => update_player_location(player, &console, &viewport),
40-
}
41-
}
42-
}
43-
44-
fn update_player_location(player: &mut Player, console: &ConsoleEngine, viewport: &Viewport) {
45-
if console.is_key_pressed(KeyCode::Up) {
46-
player.location.y = check_lower_bounds(0, player.location.y, -1);
47-
} else if console.is_key_pressed(KeyCode::Down) {
48-
player.location.y = check_upper_bounds(viewport.height, player.location.y, 1);
49-
} else if console.is_key_pressed(KeyCode::Left) {
50-
player.location.x = check_lower_bounds(0, player.location.x, -1);
51-
} else if console.is_key_pressed(KeyCode::Right) {
52-
player.location.x = check_upper_bounds(viewport.width, player.location.x, 1);
53-
}
54-
}
55-
56-
fn check_upper_bounds(boundary: u32, current_location: i32, movement: i32) -> i32 {
57-
if current_location + movement >= (boundary - 1) as i32 {
58-
info!("Entity hit the boundary.");
59-
return current_location;
60-
}
61-
current_location + movement
62-
}
63-
64-
fn check_lower_bounds(boundary: u32, current_location: i32, movement: i32) -> i32 {
65-
if current_location + movement <= boundary as i32 {
66-
info!("Entity hit the boundary.");
67-
return current_location;
68-
}
69-
current_location + movement
70-
}
71-
72-
fn draw_entities(console: &mut ConsoleEngine, entity_map: &HashMap<Uuid, Entity>) {
73-
for entity in entity_map.values() {
74-
match entity {
75-
Entity::Player(player) => console.print(
76-
player.location.x,
77-
player.location.y,
78-
&player.character_icon.to_string(),
79-
),
80-
}
81-
}
82-
console.draw();
83-
}
84-
85-
fn draw_viewport_boundary(console: &mut ConsoleEngine, viewport: &Viewport) {
86-
console.rect(
87-
0,
88-
0,
89-
(viewport.width - 1) as i32,
90-
(viewport.height - 1) as i32,
91-
pixel::pxl('#'),
92-
);
93-
}
94-
9537
fn should_quit(console: &ConsoleEngine) -> bool {
9638
console.is_key_pressed_with_modifier(KeyCode::Char('q'), KeyModifiers::CONTROL)
9739
}

src/entity.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,68 @@
1+
use crate::entity::door::Door;
12
use crate::entity::player::Player;
3+
use crate::entity::wall::Wall;
4+
use crate::world_map::WorldMap;
5+
use console_engine::ConsoleEngine;
6+
use std::collections::HashMap;
7+
use uuid::Uuid;
28

9+
pub(crate) mod door;
310
pub(crate) mod player;
11+
pub(crate) mod wall;
412

13+
#[derive(Clone, Copy)]
514
pub enum Entity {
615
Player(Player),
16+
Wall(Wall),
17+
Door(Door),
18+
EmptySpace,
19+
Boundary,
20+
NewLine,
21+
CarriageReturn,
22+
EndOfFile,
723
}
824

25+
impl Entity {
26+
pub fn character(&self) -> char {
27+
match self {
28+
Entity::Player(player) => player.character_icon,
29+
Entity::Wall(wall) => wall.character_icon,
30+
Entity::Door(door) => door.character_icon,
31+
Entity::EmptySpace => ' ',
32+
Entity::Boundary => '#',
33+
Entity::NewLine => ' ',
34+
Entity::CarriageReturn => ' ',
35+
Entity::EndOfFile => ' ',
36+
}
37+
}
38+
39+
pub fn update_entities(
40+
console: &ConsoleEngine,
41+
entity_map: &mut HashMap<Uuid, Entity>,
42+
world_map: &WorldMap,
43+
) {
44+
for entity in entity_map.values_mut() {
45+
if let Entity::Player(ref mut player) = entity {
46+
Player::update_player_location(player, &console, &world_map)
47+
}
48+
}
49+
}
50+
}
51+
52+
#[derive(Clone, Copy)]
953
pub struct Location {
1054
pub x: i32,
1155
pub y: i32,
1256
}
57+
58+
#[derive(Clone, Copy)]
59+
pub enum Collidable {
60+
True,
61+
False,
62+
}
63+
64+
#[derive(Clone, Copy)]
65+
pub enum OpenState {
66+
Open,
67+
Closed,
68+
}

src/entity/door.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use crate::entity::{Collidable, Location, OpenState};
2+
3+
#[derive(Clone, Copy)]
4+
pub struct Door {
5+
pub location: Location,
6+
pub character_icon: char,
7+
pub collidable: Collidable,
8+
pub open_state: OpenState,
9+
}
10+
11+
impl Door {
12+
pub fn new(x: i32, y: i32, open_state: OpenState) -> Door {
13+
Door {
14+
location: Location { x, y },
15+
character_icon: match open_state {
16+
OpenState::Open => '+',
17+
OpenState::Closed => 'x',
18+
},
19+
collidable: match open_state {
20+
OpenState::Open => Collidable::False,
21+
OpenState::Closed => Collidable::True,
22+
},
23+
open_state,
24+
}
25+
}
26+
}

src/entity/player.rs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,62 @@
1-
use crate::entity::Location;
1+
use crate::entity::{Collidable, Entity, Location};
2+
use crate::world_map::WorldMap;
3+
use console_engine::{Color, ConsoleEngine, KeyCode};
4+
use std::collections::HashMap;
5+
use uuid::Uuid;
26

7+
#[derive(Clone, Copy)]
38
pub struct Player {
49
pub location: Location,
510
pub character_icon: char,
11+
pub collidable: Collidable,
12+
pub colour: Color,
613
}
714

815
impl Player {
9-
pub fn new() -> Player {
16+
pub fn new(x: i32, y: i32) -> Player {
1017
Player {
11-
location: Location { x: 5, y: 5 },
18+
location: Location { x, y },
1219
character_icon: '@',
20+
collidable: Collidable::True,
21+
colour: Color::Magenta,
1322
}
1423
}
24+
25+
pub fn create_player(entity_map: &mut HashMap<Uuid, Entity>) -> Uuid {
26+
let uuid = Uuid::new_v4();
27+
entity_map.insert(uuid, Entity::Player(Player::new(5, 5)));
28+
uuid
29+
}
30+
31+
pub fn update_player_location(
32+
player: &mut Player,
33+
console: &ConsoleEngine,
34+
world_map: &WorldMap,
35+
) {
36+
if console.is_key_held(KeyCode::Up) {
37+
player.location.y = check_lower_bounds(0, player.location.y, -1);
38+
} else if console.is_key_held(KeyCode::Down) {
39+
player.location.y = check_upper_bounds(world_map.boundary_y(), player.location.y, 1);
40+
} else if console.is_key_held(KeyCode::Left) {
41+
player.location.x = check_lower_bounds(0, player.location.x, -1);
42+
} else if console.is_key_held(KeyCode::Right) {
43+
player.location.x = check_upper_bounds(world_map.boundary_x(), player.location.x, 1);
44+
}
45+
}
46+
}
47+
48+
fn check_upper_bounds(boundary: &u32, current_location: i32, movement: i32) -> i32 {
49+
if current_location + movement >= (boundary - 1) as i32 {
50+
info!("Player hit the map boundary.");
51+
return current_location;
52+
}
53+
current_location + movement
54+
}
55+
56+
fn check_lower_bounds(boundary: u32, current_location: i32, movement: i32) -> i32 {
57+
if current_location + movement <= boundary as i32 {
58+
info!("Player hit the map boundary.");
59+
return current_location;
60+
}
61+
current_location + movement
1562
}

src/entity/wall.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use crate::entity::{Collidable, Location};
2+
3+
#[derive(Clone, Copy)]
4+
pub struct Wall {
5+
pub location: Location,
6+
pub character_icon: char,
7+
pub collidable: Collidable,
8+
}
9+
10+
impl Wall {
11+
pub fn new(x: i32, y: i32, character_icon: char) -> Wall {
12+
Wall {
13+
location: Location { x, y },
14+
character_icon,
15+
collidable: Collidable::True,
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)