aboutsummaryrefslogtreecommitdiff
path: root/src/camera.rs
blob: b158dee11421bb337830818d5afa47285d0e69a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use crate::map::{Map, MapCell};
use crate::util::{Side, Step};
use crate::vec2::Vec2;

use minifb::{Key, Window};

pub struct Intersection {
    pub side: Side,
    pub step: Vec2<Step>,
    pub map_coordinates: Vec2<usize>,
    pub wall_offset: Vec2<f64>,
}

pub struct Ray {
    pub direction: Vec2<f64>,
    pub intersections: Vec<Intersection>,
}

pub struct Camera {
    pub position: Vec2<f64>,
    pub direction: Vec2<f64>,
    pub plane: Vec2<f64>,
    pub height: f64,
}

impl Camera {
    pub fn get_ray(&self, x: usize, screen_width: usize) -> Ray {
        let camera_x: f64 = 2.0 * (x as f64) / (screen_width as f64) - 1.0;
        Ray {
            direction: &self.direction + &self.plane * camera_x,
            intersections: Vec::new(),
        }
    }

    pub fn update_position_with_keys(&mut self, delta: f64, window: &Window, world: &Map) {
        let move_speed = delta * 5.0;
        let rot_speed = delta * 3.0;

        if window.is_key_down(Key::W) {
            if let Some(MapCell::Empty {
                ceiling_texture: _,
                floor_texture: _,
                fog: _,
                fog_color: _,
            }) = world.at(&(&self.position + &self.direction * move_speed).as_usize())
            {
                self.position += &self.direction * move_speed;
            }
        }
        if window.is_key_down(Key::S) {
            if let Some(MapCell::Empty {
                ceiling_texture: _,
                floor_texture: _,
                fog: _,
                fog_color: _,
            }) = world.at(&(&self.position - &self.direction * move_speed).as_usize())
            {
                self.position -= &self.direction * move_speed;
            }
        }
        if window.is_key_down(Key::A) {
            let mut direction = self.direction.clone();
            direction.rotate(-std::f64::consts::PI / 2.0);
            if let Some(MapCell::Empty {
                ceiling_texture: _,
                floor_texture: _,
                fog: _,
                fog_color: _,
            }) = world.at(&(&self.position - &direction * move_speed).as_usize())
            {
                self.position -= &direction * (move_speed / 1.5);
            }
        }
        if window.is_key_down(Key::D) {
            let mut direction = self.direction.clone();
            direction.rotate(std::f64::consts::PI / 2.0);
            if let Some(MapCell::Empty {
                ceiling_texture: _,
                floor_texture: _,
                fog: _,
                fog_color: _,
            }) = world.at(&(&self.position - &direction * move_speed).as_usize())
            {
                self.position -= &direction * (move_speed / 1.5);
            }
        }
        if window.is_key_down(Key::Left) {
            self.direction.rotate(rot_speed);
            self.plane.rotate(rot_speed);
        }
        if window.is_key_down(Key::Right) {
            self.direction.rotate(-rot_speed);
            self.plane.rotate(-rot_speed);
        }
    }
}