Skip to content

Commit 1290b70

Browse files
authored
GameScene subclass approach. (#51)
* 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.
1 parent 82d8f9a commit 1290b70

29 files changed

+262
-257
lines changed
Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
1+
#include <bave/services/resources.hpp>
12
#include <spaced/game/enemies/creep.hpp>
23

3-
namespace spaced {
4+
namespace spaced::enemy {
5+
using bave::Resources;
46
using bave::Seconds;
7+
using bave::Texture;
8+
9+
Creep::Creep(bave::Services const& services) : Enemy(services, "Creep") {
10+
m_sprite.set_texture(services.get<Resources>().get<Texture>("images/creep_ship.png"));
11+
m_sprite.set_size(glm::vec2{80.0f});
12+
health = 2.0f;
13+
}
514

615
void Creep::tick(Seconds const dt, bool const in_play) {
7-
Enemy::tick(dt, in_play);
816
if (!in_play) { return; }
917

10-
sprite.transform.position.x -= x_speed * dt.count();
11-
if (sprite.transform.position.x < -0.5f * (get_layout().world_space.x + sprite.get_shape().size.x)) { set_destroyed(); }
18+
m_sprite.transform.position.x -= x_speed * dt.count();
19+
if (m_sprite.transform.position.x < -0.5f * (get_layout().world_space.x + m_sprite.get_shape().size.x)) { set_destroyed(); }
20+
21+
update_health_bar();
1222
}
13-
} // namespace spaced
23+
} // namespace spaced::enemy
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#pragma once
22
#include <spaced/game/enemy.hpp>
33

4-
namespace spaced {
4+
namespace spaced::enemy {
55
class Creep : public Enemy {
66
public:
7-
explicit Creep(bave::Services const& services) : Enemy(services, "Creep") {}
7+
explicit Creep(bave::Services const& services);
88

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

1111
float x_speed{100.0f};
1212
};
13-
} // namespace spaced
13+
} // namespace spaced::enemy

src/spaced/spaced/game/enemies/creep_factory.cpp

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/spaced/spaced/game/enemies/creep_factory.hpp

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/spaced/spaced/game/enemy.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ Enemy::Enemy(Services const& services, std::string_view const type) : m_layout(&
2222
setup(init_size_v, random_in_range(y_min, y_max));
2323

2424
m_health_bar.set_style(services.get<Styles>().progress_bars["enemy"]);
25+
26+
update_health_bar();
2527
}
2628

2729
auto Enemy::get_bounds() const -> bave::Rect<> {
28-
if (hitbox) { return Rect<>::from_size(*hitbox, sprite.transform.position); }
29-
return sprite.get_bounds();
30+
if (m_hitbox) { return Rect<>::from_size(*m_hitbox, m_sprite.transform.position); }
31+
return m_sprite.get_bounds();
3032
}
3133

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

43-
void Enemy::tick(Seconds const /*dt*/, bool const /*in_play*/) {
44-
m_health_bar.position = sprite.transform.position;
45-
m_health_bar.position.y += 0.5f * sprite.get_shape().size.y + 20.0f;
46-
m_health_bar.size = {sprite.get_shape().size.x, 10.0f};
45+
void Enemy::update_health_bar() {
46+
m_health_bar.position = m_sprite.transform.position;
47+
m_health_bar.position.y += 0.5f * m_sprite.get_shape().size.y + 20.0f;
48+
m_health_bar.size = {m_sprite.get_shape().size.x, 10.0f};
4749
m_health_bar.set_progress(health.get_hit_points() / health.get_total_hit_points());
4850
}
4951

5052
void Enemy::draw(Shader& shader) const {
51-
sprite.draw(shader);
53+
m_sprite.draw(shader);
5254
m_health_bar.draw(shader);
5355
}
5456

5557
void Enemy::setup(glm::vec2 max_size, float y_position) {
5658
auto rounded_quad = RoundedQuad{};
5759
rounded_quad.size = max_size;
5860
rounded_quad.corner_radius = 0.2f * max_size.x;
59-
sprite.set_shape(rounded_quad);
60-
sprite.transform.position.x = 0.5f * (get_layout().world_space.x + rounded_quad.size.x);
61-
sprite.transform.position.y = y_position;
61+
m_sprite.set_shape(rounded_quad);
62+
m_sprite.transform.position.x = 0.5f * (get_layout().world_space.x + rounded_quad.size.x);
63+
m_sprite.transform.position.y = y_position;
6264
}
6365

6466
void Enemy::do_inspect() {

src/spaced/spaced/game/enemy.hpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,35 +15,40 @@ class Enemy : public IDamageable, public bave::IDrawable {
1515

1616
[[nodiscard]] auto get_instigator() const -> Instigator final { return Instigator::eEnemy; }
1717
[[nodiscard]] auto get_bounds() const -> bave::Rect<> override;
18+
[[nodiscard]] auto get_position() const -> glm::vec2 { return m_sprite.transform.position; }
19+
1820
auto take_damage(float damage) -> bool override;
1921
void force_death() override;
2022

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

25-
virtual void tick(bave::Seconds dt, bool in_play);
27+
virtual void tick(bave::Seconds dt, bool in_play) = 0;
2628
void draw(bave::Shader& shader) const override;
2729

2830
void setup(glm::vec2 max_size, float y_position);
31+
void update_health_bar();
2932

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

3235
void inspect() {
3336
if constexpr (bave::debug_v) { do_inspect(); }
3437
}
3538

36-
bave::Sprite sprite{};
37-
std::optional<glm::vec2> hitbox{};
3839
Health health{};
3940
std::int64_t points{10};
4041

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

44-
private:
45+
protected:
46+
bave::Sprite m_sprite{};
47+
std::optional<glm::vec2> m_hitbox{};
48+
4549
virtual void do_inspect();
4650

51+
private:
4752
bave::NotNull<Layout const*> m_layout;
4853

4954
bave::ui::ProgressBar m_health_bar;

src/spaced/spaced/game/enemy_factory.cpp

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/spaced/spaced/game/enemy_factory.hpp

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/spaced/spaced/game/player.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Player : public bave::IDrawable {
1515
public:
1616
struct State {
1717
std::span<bave::NotNull<IDamageable*> const> targets{};
18-
std::span<bave::NotNull<IPowerup*> const> powerups{};
18+
std::span<bave::NotNull<Powerup*> const> powerups{};
1919
};
2020

2121
explicit Player(bave::Services const& services, std::unique_ptr<IController> controller);

src/spaced/spaced/game/powerups/pu_base.cpp renamed to src/spaced/spaced/game/powerup.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <bave/services/resources.hpp>
2-
#include <spaced/game/powerups/pu_base.hpp>
2+
#include <spaced/game/powerup.hpp>
33

44
namespace spaced {
55
using bave::Circle;
@@ -9,7 +9,7 @@ using bave::Seconds;
99
using bave::Services;
1010
using bave::Shader;
1111

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

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

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

35-
void PUBase::draw(Shader& shader) const {
35+
void Powerup::draw(Shader& shader) const {
3636
shape.draw(shader);
3737
emitter.draw(shader);
3838
}
3939

40-
void PUBase::activate(Player& player) {
40+
void Powerup::activate(Player& player) {
4141
do_activate(player);
4242
m_destroyed = true;
4343
}

0 commit comments

Comments
 (0)