summaryrefslogtreecommitdiffhomepage
path: root/Player.cpp
blob: 94371c1203dca5bbcdbea15e970026abef074eee (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
97
98
#include "Player.h"

#include <algorithm>
#include <memory>

#include <raylib.h>

#include "KeyboardController.h"


static constexpr float ACCELERATION {1800};
static constexpr float MAX_SPEED {180};
static constexpr float DAMP {2200};
static constexpr float MARGIN {0.3f};
static constexpr float HIT_INVUL {1.2f};
static constexpr float RADIUS {4};


static float damped_velocity(float dt, float direction, float velocity);


Player::Player() :
    m_invulnerability {HIT_INVUL / 2.f},
    m_position {400, 450},
    m_velocity {0, 0},
    m_playground {0, 0, 800, 600},
    m_controller {std::make_unique<KeyboardController>()}
{
}


void
Player::update(const float dt)
{
    const auto direction = m_controller->direction();
    m_velocity.x = std::clamp(damped_velocity(dt, direction.x, m_velocity.x), -MAX_SPEED, MAX_SPEED);
    m_velocity.y = std::clamp(damped_velocity(dt, direction.y, m_velocity.y), -MAX_SPEED, MAX_SPEED);
    m_position.x += m_velocity.x * dt;
    m_position.y += m_velocity.y * dt;
    if (m_position.y < m_playground.y + RADIUS || m_position.y > m_playground.y + m_playground.height - RADIUS) {
        m_position.y =
            m_position.y < m_playground.y + m_playground.height / 2 ?
            m_playground.y + RADIUS :
            m_playground.y + m_playground.height - RADIUS;
        m_velocity.y = 0;
    }
    if (m_position.x < m_playground.x + RADIUS || m_position.x > m_playground.x + m_playground.width - RADIUS) {
        m_position.x =
            m_position.x < m_playground.x + m_playground.width / 2 ?
            m_playground.x + RADIUS :
            m_playground.x + m_playground.width - RADIUS;
        m_velocity.x = 0;
    }
    m_invulnerability -= dt;
}


void
Player::draw()
{
    DrawCircle(m_position.x, m_position.y, RADIUS, m_invulnerability > 0 ? RED : LIGHTGRAY);
}


void
Player::hit()
{
    m_invulnerability = HIT_INVUL;
}


float
damped_velocity(const float dt, const float direction, const float velocity)
{
    if (direction > 0 || direction < 0)
        return velocity + direction * ACCELERATION * dt;
    if (velocity > 0) {
        if (velocity > MARGIN) {
            const float next = velocity - dt * DAMP;
            if (next < MARGIN)
                return 0;
            else
                return next;
        }
        return 0;
    }
    if (velocity < 0) {
        if (velocity < MARGIN) {
            const float next = velocity + dt * DAMP;
            if (next > MARGIN)
                return 0;
            else
                return next;
        }
        return 0;
    }
    return 0;
}