diff --git a/src/engine.rs b/src/engine.rs index 4f0a53e..7d3cb7b 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1,6 +1,7 @@ extern crate piston_window; use piston_window::*; -use std::f64::consts; + +use std::f64::consts::*; #[derive(PartialEq, Debug)] struct Position { @@ -13,11 +14,23 @@ struct Player { angle: f64, // radian or degree } +pub enum Tile { + Empty, + Wall, +} + +pub struct Level { + pub width: u16, + pub height: u16, + pub tiles: Vec, +} + pub struct Engine { w: f64, h: f64, horiz_fov: f64, player: Player, + level: Level, } impl Engine { @@ -29,12 +42,34 @@ impl Engine { player: Player { pos: Position { x: 2., y: 2. }, angle: 0., - } + }, + level: Level { + width: 0, + height: 0, + tiles: vec![], + }, } } - fn closest_point(pos: Position, angle: f64) -> Position { - return Position {x: 2., y: 2.} + fn closest_point(pos: &Position, angle: f64) -> (Tile, Position) { + // 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) { @@ -64,12 +99,17 @@ impl Engine { let width = self.w as i32; for n in 0..width { // cast a ray + let (tile, pos) = Engine::closest_point(&self.player.pos, ray_angle); // see what wall it hits // compute wall height // draw wall portion ray_angle += step; } } + + pub fn load_level(&mut self, level: Level) { + self.level = level; + } } #[cfg(test)] diff --git a/src/main.rs b/src/main.rs index 536cc3d..f93e77f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,8 @@ extern crate piston_window; use piston_window::*; -mod engine; -enum Tile { - Empty, - Wall, -} +mod engine; +use engine::Tile; fn main() { let mut window: PistonWindow = @@ -15,18 +12,24 @@ fn main() { .build() .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::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, ]; - - let mut engine = engine::Engine::new(window.size()); + let level = engine::Level { + width:5, + height: 5, + tiles + }; + engine.load_level(level); while let Some(event) = window.next() { - window.draw_2d(&event, |context, graphics, device| { + window.draw_2d(&event, |context, graphics, _device| { engine.render(context, graphics); }); }