Dungeon building blocks
This commit is contained in:
parent
57bdd8de1e
commit
f5b9c3d257
144
src/main.rs
144
src/main.rs
@ -3,14 +3,15 @@
|
|||||||
#![allow(unused_mut)]
|
#![allow(unused_mut)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use std::cmp;
|
||||||
use tcod::colors::*;
|
use tcod::colors::*;
|
||||||
use tcod::console::*;
|
use tcod::console::*;
|
||||||
|
|
||||||
const MAP_WIDTH: i32 = 80;
|
|
||||||
const MAP_HEIGHT: i32 = 45;
|
|
||||||
const SCREEN_WIDTH: i32 = 80;
|
const SCREEN_WIDTH: i32 = 80;
|
||||||
const SCREEN_HEIGHT: i32 = 50;
|
const SCREEN_HEIGHT: i32 = 50;
|
||||||
const FPS: i32 = 20;
|
const FPS: i32 = 20;
|
||||||
|
const MAP_WIDTH: i32 = 80;
|
||||||
|
const MAP_HEIGHT: i32 = 45;
|
||||||
const COLOR_DARK_WALL: Color = Color { r: 0, g: 0, b: 100 };
|
const COLOR_DARK_WALL: Color = Color { r: 0, g: 0, b: 100 };
|
||||||
const COLOR_DARK_GROUND: Color = Color {
|
const COLOR_DARK_GROUND: Color = Color {
|
||||||
r: 50,
|
r: 50,
|
||||||
@ -23,6 +24,7 @@ struct Tcod {
|
|||||||
con: Offscreen,
|
con: Offscreen,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct Object {
|
struct Object {
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
@ -35,10 +37,12 @@ impl Object {
|
|||||||
Object { x, y, char, color }
|
Object { x, y, char, color }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move by given amount
|
// Move by given amount, if the destination is not blocked
|
||||||
pub fn move_by(&mut self, dx: i32, dy: i32) {
|
pub fn move_by(&mut self, dx: i32, dy: i32, game: &Game) {
|
||||||
self.x += dx;
|
if !game.map[(self.x + dx) as usize][(self.y + dy) as usize].blocked {
|
||||||
self.y += dy;
|
self.x += dx;
|
||||||
|
self.y += dy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the color and then draw the character that represents this object at its position
|
// Set the color and then draw the character that represents this object at its position
|
||||||
@ -70,11 +74,36 @@ impl Tile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_keys(tcod: &mut Tcod, player: &mut Object) -> bool {
|
type Map = Vec<Vec<Tile>>;
|
||||||
|
|
||||||
|
struct Game {
|
||||||
|
map: Map,
|
||||||
|
}
|
||||||
|
|
||||||
|
// A rectangle on the map, used to characterise a room.
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
struct Rect {
|
||||||
|
x1: i32,
|
||||||
|
y1: i32,
|
||||||
|
x2: i32,
|
||||||
|
y2: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rect {
|
||||||
|
pub fn new(x: i32, y: i32, w: i32, h: i32) -> Self {
|
||||||
|
Rect {
|
||||||
|
x1: x,
|
||||||
|
y1: y,
|
||||||
|
x2: x + w,
|
||||||
|
y2: y + h,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_keys(tcod: &mut Tcod, game: &Game, player: &mut Object) -> bool {
|
||||||
use tcod::input::Key;
|
use tcod::input::Key;
|
||||||
use tcod::input::KeyCode::*;
|
use tcod::input::KeyCode::*;
|
||||||
|
|
||||||
// todo: handle keys
|
|
||||||
let key = tcod.root.wait_for_keypress(true);
|
let key = tcod.root.wait_for_keypress(true);
|
||||||
match key {
|
match key {
|
||||||
Key {
|
Key {
|
||||||
@ -88,16 +117,86 @@ fn handle_keys(tcod: &mut Tcod, player: &mut Object) -> bool {
|
|||||||
}
|
}
|
||||||
Key { code: Escape, .. } => return true, // exit game
|
Key { code: Escape, .. } => return true, // exit game
|
||||||
|
|
||||||
Key { code: Up, .. } => player.move_by(0, -1),
|
Key { code: Up, .. } => player.move_by(0, -1, game),
|
||||||
Key { code: Down, .. } => player.move_by(0, 1),
|
Key { code: Down, .. } => player.move_by(0, 1, game),
|
||||||
Key { code: Left, .. } => player.move_by(-1, 0),
|
Key { code: Left, .. } => player.move_by(-1, 0, game),
|
||||||
Key { code: Right, .. } => player.move_by(1, 0),
|
Key { code: Right, .. } => player.move_by(1, 0, game),
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_map() -> Map {
|
||||||
|
// Fill the map with unblocked tiles
|
||||||
|
let mut map = vec![vec![Tile::wall(); MAP_HEIGHT as usize]; MAP_WIDTH as usize];
|
||||||
|
|
||||||
|
// Create two rooms
|
||||||
|
let room1 = Rect::new(20, 15, 10, 15);
|
||||||
|
let room2 = Rect::new(50, 15, 10, 15);
|
||||||
|
create_room(room1, &mut map);
|
||||||
|
create_room(room2, &mut map);
|
||||||
|
create_h_tunnel(25, 55, 23, &mut map);
|
||||||
|
|
||||||
|
map
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_room(room: Rect, map: &mut Map) {
|
||||||
|
// Go through the tiles in the rectangle and make them passable
|
||||||
|
for x in (room.x1 + 1)..room.x2 {
|
||||||
|
for y in (room.y1 + 1)..room.y2 {
|
||||||
|
map[x as usize][y as usize] = Tile::empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_h_tunnel(x1: i32, x2: i32, y: i32, map: &mut Map) {
|
||||||
|
// Horizontal tunnel. `min()` and `max()` are used in case
|
||||||
|
// `x1 > x2`
|
||||||
|
for x in cmp::min(x1, x2)..(cmp::max(x1, x2) + 1) {
|
||||||
|
map[x as usize][y as usize] = Tile::empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_v_tunnel(y1: i32, y2: i32, x: i32, map: &mut Map) {
|
||||||
|
// Vertical tunnel
|
||||||
|
for y in cmp::min(y1, y2)..(cmp::max(y1, y2) + 1) {
|
||||||
|
map[x as usize][y as usize] = Tile::empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_all(tcod: &mut Tcod, game: &Game, objects: &[Object]) {
|
||||||
|
// Draw all objects in the list
|
||||||
|
for object in objects {
|
||||||
|
object.draw(&mut tcod.con);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go through all tiles and set their background color
|
||||||
|
for y in 0..MAP_HEIGHT {
|
||||||
|
for x in 0..MAP_WIDTH {
|
||||||
|
let wall = game.map[x as usize][y as usize].block_sight;
|
||||||
|
if wall {
|
||||||
|
tcod.con
|
||||||
|
.set_char_background(x, y, COLOR_DARK_WALL, BackgroundFlag::Set);
|
||||||
|
} else {
|
||||||
|
tcod.con
|
||||||
|
.set_char_background(x, y, COLOR_DARK_GROUND, BackgroundFlag::Set)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blit contents of "con" to the root console
|
||||||
|
blit(
|
||||||
|
&tcod.con,
|
||||||
|
(0, 0),
|
||||||
|
(MAP_WIDTH, MAP_HEIGHT),
|
||||||
|
&mut tcod.root,
|
||||||
|
(0, 0),
|
||||||
|
1.0,
|
||||||
|
1.0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tcod::system::set_fps(FPS);
|
tcod::system::set_fps(FPS);
|
||||||
|
|
||||||
@ -108,12 +207,12 @@ fn main() {
|
|||||||
.title("Rust/libtcod tutorial")
|
.title("Rust/libtcod tutorial")
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
let con = Offscreen::new(SCREEN_WIDTH, SCREEN_HEIGHT);
|
let con = Offscreen::new(MAP_WIDTH, MAP_HEIGHT);
|
||||||
|
|
||||||
let mut tcod = Tcod { root, con };
|
let mut tcod = Tcod { root, con };
|
||||||
|
|
||||||
// Create player object
|
// Create player object
|
||||||
let player = Object::new(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, '@', WHITE);
|
let player = Object::new(25, 23, '@', WHITE);
|
||||||
|
|
||||||
// // Create an NPC
|
// // Create an NPC
|
||||||
let npc = Object::new(SCREEN_WIDTH / 2 - 5, SCREEN_HEIGHT / 2, '@', YELLOW);
|
let npc = Object::new(SCREEN_WIDTH / 2 - 5, SCREEN_HEIGHT / 2, '@', YELLOW);
|
||||||
@ -121,6 +220,11 @@ fn main() {
|
|||||||
// List of objects in the world
|
// List of objects in the world
|
||||||
let mut objects = [player, npc];
|
let mut objects = [player, npc];
|
||||||
|
|
||||||
|
let game = Game {
|
||||||
|
// Generate map
|
||||||
|
map: make_map(),
|
||||||
|
};
|
||||||
|
|
||||||
while !tcod.root.window_closed() {
|
while !tcod.root.window_closed() {
|
||||||
tcod.con.clear();
|
tcod.con.clear();
|
||||||
|
|
||||||
@ -128,19 +232,11 @@ fn main() {
|
|||||||
object.draw(&mut tcod.con)
|
object.draw(&mut tcod.con)
|
||||||
}
|
}
|
||||||
|
|
||||||
blit(
|
render_all(&mut tcod, &game, &objects);
|
||||||
&tcod.con,
|
|
||||||
(0, 0),
|
|
||||||
(SCREEN_WIDTH, SCREEN_HEIGHT),
|
|
||||||
&mut tcod.root,
|
|
||||||
(0, 0),
|
|
||||||
1.0,
|
|
||||||
1.0,
|
|
||||||
);
|
|
||||||
tcod.root.flush();
|
tcod.root.flush();
|
||||||
|
|
||||||
let player = &mut objects[0];
|
let player = &mut objects[0];
|
||||||
let exit = handle_keys(&mut tcod, player);
|
let exit = handle_keys(&mut tcod, &game, player);
|
||||||
if exit {
|
if exit {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user