Skip to content

Commit

Permalink
GameScene subclass approach. (#51)
Browse files Browse the repository at this point in the history
* Replace `IScorer` with `SigPlayerScored`.

* Starfield density in prefs.

* Add `GameScene` subclass: `EndlessScene`.

* Make `Creep` self dependent.

Simplify `CreepFactory` in preparation for removal.

* Move `Creep` spawning logic into `EndlessScene`.

* Remove `EnemyFactory` and dependencies.

* Move powerup spawnage to `EndlessScene`.

* Refactor powerup hierarchy.

* Use braced init for aggregate member.

* Cleanup.

* Make `SpawnTimer` polymorphic, store vector.
  • Loading branch information
karnkaul authored Jun 26, 2024
1 parent 82d8f9a commit 1290b70
Show file tree
Hide file tree
Showing 29 changed files with 262 additions and 257 deletions.
20 changes: 15 additions & 5 deletions src/spaced/spaced/game/enemies/creep.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
#include <bave/services/resources.hpp>
#include <spaced/game/enemies/creep.hpp>

namespace spaced {
namespace spaced::enemy {
using bave::Resources;
using bave::Seconds;
using bave::Texture;

Creep::Creep(bave::Services const& services) : Enemy(services, "Creep") {
m_sprite.set_texture(services.get<Resources>().get<Texture>("images/creep_ship.png"));
m_sprite.set_size(glm::vec2{80.0f});
health = 2.0f;
}

void Creep::tick(Seconds const dt, bool const in_play) {
Enemy::tick(dt, in_play);
if (!in_play) { return; }

sprite.transform.position.x -= x_speed * dt.count();
if (sprite.transform.position.x < -0.5f * (get_layout().world_space.x + sprite.get_shape().size.x)) { set_destroyed(); }
m_sprite.transform.position.x -= x_speed * dt.count();
if (m_sprite.transform.position.x < -0.5f * (get_layout().world_space.x + m_sprite.get_shape().size.x)) { set_destroyed(); }

update_health_bar();
}
} // namespace spaced
} // namespace spaced::enemy
6 changes: 3 additions & 3 deletions src/spaced/spaced/game/enemies/creep.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#pragma once
#include <spaced/game/enemy.hpp>

namespace spaced {
namespace spaced::enemy {
class Creep : public Enemy {
public:
explicit Creep(bave::Services const& services) : Enemy(services, "Creep") {}
explicit Creep(bave::Services const& services);

void tick(bave::Seconds dt, bool in_play) override;

float x_speed{100.0f};
};
} // namespace spaced
} // namespace spaced::enemy
22 changes: 0 additions & 22 deletions src/spaced/spaced/game/enemies/creep_factory.cpp

This file was deleted.

15 changes: 0 additions & 15 deletions src/spaced/spaced/game/enemies/creep_factory.hpp

This file was deleted.

22 changes: 12 additions & 10 deletions src/spaced/spaced/game/enemy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ Enemy::Enemy(Services const& services, std::string_view const type) : m_layout(&
setup(init_size_v, random_in_range(y_min, y_max));

m_health_bar.set_style(services.get<Styles>().progress_bars["enemy"]);

update_health_bar();
}

auto Enemy::get_bounds() const -> bave::Rect<> {
if (hitbox) { return Rect<>::from_size(*hitbox, sprite.transform.position); }
return sprite.get_bounds();
if (m_hitbox) { return Rect<>::from_size(*m_hitbox, m_sprite.transform.position); }
return m_sprite.get_bounds();
}

auto Enemy::take_damage(float const damage) -> bool {
Expand All @@ -40,25 +42,25 @@ void Enemy::force_death() {
m_health_bar.set_progress(0.0f);
}

void Enemy::tick(Seconds const /*dt*/, bool const /*in_play*/) {
m_health_bar.position = sprite.transform.position;
m_health_bar.position.y += 0.5f * sprite.get_shape().size.y + 20.0f;
m_health_bar.size = {sprite.get_shape().size.x, 10.0f};
void Enemy::update_health_bar() {
m_health_bar.position = m_sprite.transform.position;
m_health_bar.position.y += 0.5f * m_sprite.get_shape().size.y + 20.0f;
m_health_bar.size = {m_sprite.get_shape().size.x, 10.0f};
m_health_bar.set_progress(health.get_hit_points() / health.get_total_hit_points());
}

void Enemy::draw(Shader& shader) const {
sprite.draw(shader);
m_sprite.draw(shader);
m_health_bar.draw(shader);
}

void Enemy::setup(glm::vec2 max_size, float y_position) {
auto rounded_quad = RoundedQuad{};
rounded_quad.size = max_size;
rounded_quad.corner_radius = 0.2f * max_size.x;
sprite.set_shape(rounded_quad);
sprite.transform.position.x = 0.5f * (get_layout().world_space.x + rounded_quad.size.x);
sprite.transform.position.y = y_position;
m_sprite.set_shape(rounded_quad);
m_sprite.transform.position.x = 0.5f * (get_layout().world_space.x + rounded_quad.size.x);
m_sprite.transform.position.y = y_position;
}

void Enemy::do_inspect() {
Expand Down
13 changes: 9 additions & 4 deletions src/spaced/spaced/game/enemy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,40 @@ class Enemy : public IDamageable, public bave::IDrawable {

[[nodiscard]] auto get_instigator() const -> Instigator final { return Instigator::eEnemy; }
[[nodiscard]] auto get_bounds() const -> bave::Rect<> override;
[[nodiscard]] auto get_position() const -> glm::vec2 { return m_sprite.transform.position; }

auto take_damage(float damage) -> bool override;
void force_death() override;

[[nodiscard]] auto is_dead() const -> bool { return health.is_dead(); }
[[nodiscard]] auto is_destroyed() const -> bool { return is_dead() || m_destroyed; }
void set_destroyed() { m_destroyed = true; }

virtual void tick(bave::Seconds dt, bool in_play);
virtual void tick(bave::Seconds dt, bool in_play) = 0;
void draw(bave::Shader& shader) const override;

void setup(glm::vec2 max_size, float y_position);
void update_health_bar();

[[nodiscard]] auto get_layout() const -> Layout const& { return *m_layout; }

void inspect() {
if constexpr (bave::debug_v) { do_inspect(); }
}

bave::Sprite sprite{};
std::optional<glm::vec2> hitbox{};
Health health{};
std::int64_t points{10};

std::string death_emitter{"particles/explode.json"};
std::vector<std::string> death_sfx{"sfx/swish.wav"};

private:
protected:
bave::Sprite m_sprite{};
std::optional<glm::vec2> m_hitbox{};

virtual void do_inspect();

private:
bave::NotNull<Layout const*> m_layout;

bave::ui::ProgressBar m_health_bar;
Expand Down
22 changes: 0 additions & 22 deletions src/spaced/spaced/game/enemy_factory.cpp

This file was deleted.

25 changes: 0 additions & 25 deletions src/spaced/spaced/game/enemy_factory.hpp

This file was deleted.

2 changes: 1 addition & 1 deletion src/spaced/spaced/game/player.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Player : public bave::IDrawable {
public:
struct State {
std::span<bave::NotNull<IDamageable*> const> targets{};
std::span<bave::NotNull<IPowerup*> const> powerups{};
std::span<bave::NotNull<Powerup*> const> powerups{};
};

explicit Player(bave::Services const& services, std::unique_ptr<IController> controller);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <bave/services/resources.hpp>
#include <spaced/game/powerups/pu_base.hpp>
#include <spaced/game/powerup.hpp>

namespace spaced {
using bave::Circle;
Expand All @@ -9,7 +9,7 @@ using bave::Seconds;
using bave::Services;
using bave::Shader;

PUBase::PUBase(Services const& services, std::string_view const name) : m_services(&services), m_layout(&services.get<Layout>()), m_name(name) {
Powerup::Powerup(Services const& services, std::string_view const name) : m_services(&services), m_layout(&services.get<Layout>()), m_name(name) {
auto circle = Circle{};
circle.diameter = 40.0f;
shape.set_shape(circle);
Expand All @@ -20,7 +20,7 @@ PUBase::PUBase(Services const& services, std::string_view const name) : m_servic
emitter.config.respawn = true;
}

void PUBase::tick(Seconds const dt) {
void Powerup::tick(Seconds const dt) {
shape.transform.position.x -= speed * dt.count();
if (shape.transform.position.x < m_layout->play_area.lt.x - 0.5f * shape.get_shape().diameter) { m_destroyed = true; }

Expand All @@ -32,12 +32,12 @@ void PUBase::tick(Seconds const dt) {
emitter.tick(dt);
}

void PUBase::draw(Shader& shader) const {
void Powerup::draw(Shader& shader) const {
shape.draw(shader);
emitter.draw(shader);
}

void PUBase::activate(Player& player) {
void Powerup::activate(Player& player) {
do_activate(player);
m_destroyed = true;
}
Expand Down
33 changes: 25 additions & 8 deletions src/spaced/spaced/game/powerup.hpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
#pragma once
#include <bave/core/polymorphic.hpp>
#include <bave/core/time.hpp>
#include <bave/graphics/drawable.hpp>
#include <bave/graphics/rect.hpp>
#include <bave/graphics/particle_system.hpp>
#include <bave/graphics/shape.hpp>
#include <bave/services/services.hpp>
#include <spaced/services/layout.hpp>

namespace spaced {
class Player;

class IPowerup : public bave::IDrawable {
class Powerup : public bave::IDrawable {
public:
[[nodiscard]] virtual auto get_bounds() const -> bave::Rect<> = 0;
virtual void activate(Player& player) = 0;
explicit Powerup(bave::Services const& services, std::string_view name);

[[nodiscard]] virtual auto is_destroyed() const -> bool = 0;
void tick(bave::Seconds dt);
void draw(bave::Shader& shader) const final;

virtual void tick(bave::Seconds dt) = 0;
[[nodiscard]] auto get_bounds() const -> bave::Rect<> { return shape.get_bounds(); }
void activate(Player& player);

[[nodiscard]] auto is_destroyed() const -> bool { return m_destroyed; }

float speed{300.0f};
bave::CircleShape shape{};
bave::ParticleEmitter emitter{};

protected:
virtual void do_activate(Player& player) = 0;

bave::NotNull<bave::Services const*> m_services;
bave::NotNull<Layout const*> m_layout;
std::string_view m_name{};
bool m_emitter_ticked{};
bool m_destroyed{};
};
} // namespace spaced
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
#include <bave/services/styles.hpp>
#include <spaced/game/player.hpp>
#include <spaced/game/powerups/pu_beam.hpp>
#include <spaced/game/powerups/beam.hpp>
#include <spaced/game/weapons/gun_beam.hpp>

namespace spaced {
namespace spaced::powerup {
using bave::Services;
using bave::Styles;

PUBeam::PUBeam(Services const& services, int rounds) : PUBase(services, "Beam"), m_rounds(rounds) {
Beam::Beam(Services const& services, int rounds) : Powerup(services, "Beam"), m_rounds(rounds) {
emitter.config.lerp.tint.lo = emitter.config.lerp.tint.hi = shape.tint = services.get<Styles>().rgbas["gun_beam"];
emitter.config.lerp.tint.hi.channels.w = 0;
}

void PUBeam::do_activate(Player& player) {
void Beam::do_activate(Player& player) {
auto beam = std::make_unique<GunBeam>(*m_services);
beam->rounds = m_rounds;
player.set_special_weapon(std::move(beam));
}
} // namespace spaced
} // namespace spaced::powerup
14 changes: 14 additions & 0 deletions src/spaced/spaced/game/powerups/beam.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once
#include <spaced/game/powerup.hpp>

namespace spaced::powerup {
class Beam : public Powerup {
public:
explicit Beam(bave::Services const& services, int rounds = 2);

private:
void do_activate(Player& player) final;

int m_rounds{};
};
} // namespace spaced::powerup
35 changes: 0 additions & 35 deletions src/spaced/spaced/game/powerups/pu_base.hpp

This file was deleted.

Loading

0 comments on commit 1290b70

Please sign in to comment.