load level in engine

This commit is contained in:
Fabien Freling 2020-03-12 17:54:31 +01:00
parent dd6a65d843
commit 5774c3e488
2 changed files with 56 additions and 13 deletions

View file

@ -1,6 +1,7 @@
extern crate piston_window; extern crate piston_window;
use piston_window::*; use piston_window::*;
use std::f64::consts;
use std::f64::consts::*;
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
struct Position { struct Position {
@ -13,11 +14,23 @@ struct Player {
angle: f64, // radian or degree angle: f64, // radian or degree
} }
pub enum Tile {
Empty,
Wall,
}
pub struct Level {
pub width: u16,
pub height: u16,
pub tiles: Vec<Tile>,
}
pub struct Engine { pub struct Engine {
w: f64, w: f64,
h: f64, h: f64,
horiz_fov: f64, horiz_fov: f64,
player: Player, player: Player,
level: Level,
} }
impl Engine { impl Engine {
@ -29,12 +42,34 @@ impl Engine {
player: Player { player: Player {
pos: Position { x: 2., y: 2. }, pos: Position { x: 2., y: 2. },
angle: 0., angle: 0.,
} },
level: Level {
width: 0,
height: 0,
tiles: vec![],
},
} }
} }
fn closest_point(pos: Position, angle: f64) -> Position { fn closest_point(pos: &Position, angle: f64) -> (Tile, Position) {
return Position {x: 2., y: 2.} // First let's find the closest intersections with the grid
let dx = angle.cos();
let x_dist = if dx > 0.0 { 1.0 - pos.x.fract() } else { pos.x.fract() };
let x_relative_dist = x_dist / dx.abs();
let dy = angle.sin();
let y_dist = if dy > 0.0 { 1.0 - pos.y.fract() } else { pos.y.fract() };
let y_relative_dist = y_dist / dy.abs();
if x_relative_dist > y_relative_dist {
// first grid hit is horizontal line
} else {
// first grid hit is vertical line
}
// see Game Engine Black Book
let xstep = angle.tan();
let ystep = ((PI / 2.0) - angle).tan();
(Tile::Empty, Position {x: 2., y: 2.})
} }
pub fn render(&mut self, context: Context, graphics: &mut G2d) { pub fn render(&mut self, context: Context, graphics: &mut G2d) {
@ -64,12 +99,17 @@ impl Engine {
let width = self.w as i32; let width = self.w as i32;
for n in 0..width { for n in 0..width {
// cast a ray // cast a ray
let (tile, pos) = Engine::closest_point(&self.player.pos, ray_angle);
// see what wall it hits // see what wall it hits
// compute wall height // compute wall height
// draw wall portion // draw wall portion
ray_angle += step; ray_angle += step;
} }
} }
pub fn load_level(&mut self, level: Level) {
self.level = level;
}
} }
#[cfg(test)] #[cfg(test)]

View file

@ -1,11 +1,8 @@
extern crate piston_window; extern crate piston_window;
use piston_window::*; use piston_window::*;
mod engine;
enum Tile { mod engine;
Empty, use engine::Tile;
Wall,
}
fn main() { fn main() {
let mut window: PistonWindow = let mut window: PistonWindow =
@ -15,18 +12,24 @@ fn main() {
.build() .build()
.unwrap_or_else(|e| { panic!("Failed to build PistonWindow: {}", e) }); .unwrap_or_else(|e| { panic!("Failed to build PistonWindow: {}", e) });
let level: [Tile; 5 * 5] = [ let mut engine = engine::Engine::new(window.size());
let tiles = vec![
Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall,
Tile::Wall, Tile::Empty, Tile::Empty, Tile::Empty, Tile::Wall, Tile::Wall, Tile::Empty, Tile::Empty, Tile::Empty, Tile::Wall,
Tile::Wall, Tile::Empty, Tile::Empty, Tile::Empty, Tile::Wall, Tile::Wall, Tile::Empty, Tile::Empty, Tile::Empty, Tile::Wall,
Tile::Wall, Tile::Empty, Tile::Empty, Tile::Empty, Tile::Wall, Tile::Wall, Tile::Empty, Tile::Empty, Tile::Empty, Tile::Wall,
Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall, Tile::Wall,
]; ];
let level = engine::Level {
let mut engine = engine::Engine::new(window.size()); width:5,
height: 5,
tiles
};
engine.load_level(level);
while let Some(event) = window.next() { while let Some(event) = window.next() {
window.draw_2d(&event, |context, graphics, device| { window.draw_2d(&event, |context, graphics, _device| {
engine.render(context, graphics); engine.render(context, graphics);
}); });
} }