summaryrefslogtreecommitdiffstats
path: root/src/entity/player.rs
blob: 45f3e13baba55a89ba0da3c6ffd8d93ab5abf131 (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
use std::{
    collections::HashMap,
    fmt::{Display, Formatter},
};

use termion::event::Key;

use crate::{
    game::Command,
    physics::{Point, Vector},
    Position, Render, Velocity,
};

use crate::entity::Controllable;

#[derive(Debug, Default)]
pub struct Player {
    pub position: Point,
    pub velocity: Vector,
    render_map: HashMap<Point, char>,
}

impl Player {
    pub fn new(position: Point, velocity: Vector) -> Self {
        Self {
            position,
            velocity,
            render_map: HashMap::from([(position, '@')]),
        }
    }
}

impl Display for Player {
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
        return write!(
            f,
            "{}@",
            termion::cursor::Goto(self.position.x, self.position.y)
        );
    }
}

impl Render for Player {
    fn render_map(&self) -> &HashMap<Point, char> {
        &self.render_map
    }
}

impl Controllable for Player {
    fn handle_input(&mut self, key: Key) -> Option<Command> {
        match key {
            Key::Up | Key::Char('w') | Key::Char('k') => self.velocity.y -= 1,
            Key::Down | Key::Char('s') | Key::Char('j') => self.velocity.y += 1,
            Key::Left | Key::Char('a') | Key::Char('h') => self.velocity.x -= 1,
            Key::Right | Key::Char('d') | Key::Char('l') => self.velocity.x += 1,
            _ => return None,
        };
        Some(Command::UpdatePlayer)
    }
}

impl Position for Player {
    fn get_position(&self) -> Point {
        self.position
    }

    fn set_position<P: Into<crate::physics::Point>>(&mut self, position: P) -> crate::Result<()> {
        self.position = position.into();
        Ok(())
    }
}

impl Velocity for Player {
    fn get_velocity(&self) -> Vector {
        self.velocity
    }

    fn set_velocity<V: Into<crate::physics::Vector>>(&mut self, velocity: V) -> crate::Result<()> {
        self.velocity = velocity.into();
        Ok(())
    }
}