Skip to content

Commit

Permalink
Movement, wall collision, and movement flags added to player (#17)
Browse files Browse the repository at this point in the history
* Movement added to the player, wall collision detection added to the player, and the viewport is now set each frame

* Refactor movement code. (#18)

* Refactor movement code.

- Format all modified files.
- Use consistent casing for functions.
- Use constants where warranted.
- Store `world_space` in `Player` instead of `App*`.
- Store `Player` in `DogTales` instead of `optional<Player>`.
- Simplify bounce detection and resolution.

* Update comments.

---------

Co-authored-by: Karn Kaul <[email protected]>
  • Loading branch information
Legac3e and karnkaul authored Jan 29, 2024
1 parent 3ac64c5 commit 749f6f4
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 20 deletions.
19 changes: 9 additions & 10 deletions DogTales/src/dogtales.cpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
#include <src/dogtales.hpp>

DogTales::DogTales(bave::App& app) : bave::Driver(app) {
m_player = Player{&get_app()};
}
DogTales::DogTales(bave::App& app) : bave::Driver(app) {}

void DogTales::tick() {
auto const dt = get_app().get_dt();

m_player->tick(dt);
m_player.tick(dt);
}

void DogTales::render() const {
if (auto shader = get_app().load_shader("shaders/default.vert", "shaders/default.frag")) {
m_player->draw(*shader);
}
set_viewport_to_world_space(); // stretch sprites to fit the fixed sized world space.

if (auto shader = get_app().load_shader("shaders/default.vert", "shaders/default.frag")) { m_player.draw(*shader); }
}

void DogTales::on_key(bave::KeyInput const& key_input) {
if (key_input.key == bave::Key::eEscape && key_input.action == bave::Action::eRelease) {
get_app().shutdown();
}
if (key_input.key == bave::Key::eEscape && key_input.action == bave::Action::eRelease) { get_app().shutdown(); }
}

void DogTales::set_viewport_to_world_space() const {
get_app().get_render_device().render_view.viewport = world_space_v;
}
6 changes: 5 additions & 1 deletion DogTales/src/dogtales.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
#include <src/player.hpp>

class DogTales : public bave::Driver {
std::optional<Player> m_player{};
static constexpr glm::vec2 world_space_v{1280.0f, 720.0f};

Player m_player{world_space_v};

void tick() final;
void render() const final;

void on_key(bave::KeyInput const& key_input) final;

void set_viewport_to_world_space() const;

public:
explicit DogTales(bave::App& app);
};
26 changes: 21 additions & 5 deletions DogTales/src/player.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
#include <src/player.hpp>

Player::Player(bave::NotNull<bave::App const*> app) : m_app(app) {
m_shape.set_shape(bave::Quad{});
Player::Player(glm::vec2 const world_space) : m_world_space(world_space) { m_sprite.set_size(size_v); }

void Player::tick(bave::Seconds const dt) {
m_sprite.transform.position += m_vel * dt.count();

handle_wall_collision();
}

void Player::tick(bave::Seconds dt) {}
void Player::draw(bave::Shader& shader) const { m_sprite.draw(shader); }

void Player::handle_wall_collision() {
auto& position = m_sprite.transform.position;
// bounce_rect represents the play area for the sprite, ie the limits for its centre.
// the size is simply the total space minus the sprite size, centered at the origin.
// the second argument (glm::vec2{0.0f}) is the default value and can be omitted here.
auto const bounce_rect = bave::Rect<>::from_size(m_world_space - m_sprite.get_size(), glm::vec2{0.0f});

// if the sprite's position exceeds the play area, the corresponding velocity component needs to flip.
if (position.x < bounce_rect.top_left().x || position.x > bounce_rect.bottom_right().x) { m_vel.x *= -1.0f; }
if (position.y > bounce_rect.top_left().y || position.y < bounce_rect.bottom_right().y) { m_vel.y *= -1.0f; }

void Player::draw(bave::Shader& shader) const {
m_shape.draw(shader);
// clamp the position to the play area.
// bottom_left() gives us the minimum x and y whereas top_right() gives us the maximum.
position = glm::clamp(position, bounce_rect.bottom_left(), bounce_rect.top_right());
}
16 changes: 12 additions & 4 deletions DogTales/src/player.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
#pragma once
#include <bave/app.hpp>
#include <bave/graphics/shape.hpp>
#include <bave/graphics/sprite.hpp>

class Player {
bave::NotNull<bave::App const*> m_app;
bave::QuadShape m_shape{};
static constexpr glm::vec2 speed_v{500.0f, 500.0f};
static constexpr glm::vec2 size_v{50.0f, 90.0f};

glm::vec2 m_world_space{};

bave::Sprite m_sprite{};

glm::vec2 m_vel{speed_v};

void handle_wall_collision();

public:
explicit Player(bave::NotNull<bave::App const*> app);
explicit Player(glm::vec2 world_space);

void tick(bave::Seconds dt);
void draw(bave::Shader& shader) const;
Expand Down

0 comments on commit 749f6f4

Please sign in to comment.