Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More enemy and powerup types. #52

Merged
merged 11 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ include(FetchContent)
FetchContent_Declare(
bgf
GIT_REPOSITORY https://github.com/karnkaul/bgf

# GIT_TAG v0.1.5
GIT_TAG adc217f
GIT_TAG v0.1.7
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/bgf"
)

Expand Down
Binary file removed assets/images/creep_ship.png
Binary file not shown.
Binary file added assets/images/icon_player.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed assets/images/player_ship.png
Binary file not shown.
Binary file removed assets/images/player_ship_icon.png
Binary file not shown.
File renamed without changes
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/round_kinetic_red.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/ship_creep.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/ship_gunner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/ship_player.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/ship_trooper.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions assets/particles/exhaust.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
},
"lerp": {
"tint": {
"lo": "#36bbf5ff",
"lo": "#ffffffff",
"hi": "#00000000"
},
"scale": {
Expand All @@ -58,4 +58,4 @@
"count": 200,
"respawn": true
}
}
}
Binary file added assets/sfx/kinetic_fire1.wav
Binary file not shown.
Binary file added assets/sfx/powerup_collect.wav
Binary file not shown.
3 changes: 2 additions & 1 deletion assets/styles.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"ice": "#d6dbe1e1",
"orange": "#f75c03ff",
"gun_beam": "#bc96e6ff",
"exhaust": "#36bbf5ff",
"bg_top": "#10020eff",
"bg_bottom": "#040003ff"
},
Expand Down Expand Up @@ -36,7 +37,7 @@
"background": "#9f2b68ff",
"fill": "milk",
"corner_ratio": 0.5,
"padding": 10
"padding": 20
},
"enemy": {
"background": "orange",
Expand Down
3 changes: 3 additions & 0 deletions src/spaced/spaced/game/controllers/follow_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ auto FollowController::tick(Seconds const dt) -> float {
auto const y = tick_y(dt);

m_spring_arm.target = glm::vec2{0.0f, y};
m_spring_arm.k = is_firing() ? m_spring_k.hi : m_spring_k.lo;
m_spring_arm.tick(dt);

return m_spring_arm.position.y;
Expand All @@ -16,6 +17,8 @@ auto FollowController::tick(Seconds const dt) -> float {
void FollowController::do_inspect() {
if constexpr (bave::imgui_v) {
if (ImGui::TreeNode("spring arm")) {
ImGui::DragFloat("k.lo", &m_spring_k.lo, 1.0f, 1.0f, 1000.0f);
ImGui::DragFloat("k.hi", &m_spring_k.hi, 1.0f, 1.0f, 1000.0f);
ImGui::DragFloat("k", &m_spring_arm.k, 1.0f, 1.0f, 1000.0f);
ImGui::DragFloat("damp", &m_spring_arm.damp, 0.01f, 0.01f, 0.99f);
ImGui::DragFloat("min distance", &m_spring_arm.min_distance, 0.01f, 0.01f, 1000.0f);
Expand Down
2 changes: 2 additions & 0 deletions src/spaced/spaced/game/controllers/follow_controller.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include <bave/core/inclusive_range.hpp>
#include <spaced/game/controller.hpp>
#include <spaced/game/spring_arm.hpp>

Expand All @@ -12,5 +13,6 @@ class FollowController : public IController {
void do_inspect() override;

SpringArm m_spring_arm{};
bave::InclusiveRange<float> m_spring_k{200.0f, 40.0f};
};
} // namespace spaced
9 changes: 6 additions & 3 deletions src/spaced/spaced/game/controllers/player_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ using bave::PointerTap;
using bave::Seconds;
using bave::Services;

PlayerController::PlayerController(Services const& services) : m_layout(&services.get<Layout>()), m_gamepad_provider(&services.get<IGamepadProvider>()) {
max_y = 0.5f * m_layout->world_space.y;
min_y = -max_y; // NOLINT(cppcoreguidelines-prefer-member-initializer)
PlayerController::PlayerController(Services const& services, Type const type)
: m_layout(&services.get<Layout>()), m_gamepad_provider(&services.get<IGamepadProvider>()), m_type(type) {
auto const half_size = 0.5f * m_layout->player_size;
auto const play_area = m_layout->play_area;
max_y = play_area.lt.y - half_size.y;
min_y = play_area.rb.y + half_size.y;
}

void PlayerController::on_move(PointerMove const& pointer_move) {
Expand Down
2 changes: 1 addition & 1 deletion src/spaced/spaced/game/controllers/player_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class PlayerController : public FollowController {

[[nodiscard]] auto get_type_name() const -> std::string_view final { return type_name_v; };

explicit PlayerController(bave::Services const& services);
explicit PlayerController(bave::Services const& services, Type type);

void on_move(bave::PointerMove const& pointer_move) final;
void on_tap(bave::PointerTap const& pointer_tap) final;
Expand Down
18 changes: 6 additions & 12 deletions src/spaced/spaced/game/enemies/creep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,15 @@

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) {
if (!in_play) { return; }

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(); }
if (auto texture = services.get<Resources>().get<Texture>("images/ship_creep.png")) {
m_sprite.set_size(texture->get_size());
m_sprite.set_texture(std::move(texture));
}

update_health_bar();
health = 1.0f;
speed = 100.0f;
}
} // namespace spaced::enemy
4 changes: 0 additions & 4 deletions src/spaced/spaced/game/enemies/creep.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,5 @@ namespace spaced::enemy {
class Creep : public Enemy {
public:
explicit Creep(bave::Services const& services);

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

float x_speed{100.0f};
};
} // namespace spaced::enemy
17 changes: 17 additions & 0 deletions src/spaced/spaced/game/enemies/gunner.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <bave/services/resources.hpp>
#include <spaced/game/enemies/gunner.hpp>

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

Gunner::Gunner(bave::Services const& services, bave::NotNull<GunKinetic*> gun) : GunnerBase(services, gun, "Gunner") {
if (auto texture = services.get<Resources>().get<Texture>("images/ship_gunner.png")) {
m_sprite.set_size(texture->get_size());
m_sprite.set_texture(std::move(texture));
}

health = 2.0f;
speed = 120.0f;
}
} // namespace spaced::enemy
9 changes: 9 additions & 0 deletions src/spaced/spaced/game/enemies/gunner.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once
#include <spaced/game/enemies/gunner_base.hpp>

namespace spaced::enemy {
class Gunner : public GunnerBase {
public:
explicit Gunner(bave::Services const& services, bave::NotNull<GunKinetic*> gun);
};
} // namespace spaced::enemy
24 changes: 24 additions & 0 deletions src/spaced/spaced/game/enemies/gunner_base.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <spaced/game/enemies/gunner_base.hpp>

namespace spaced::enemy {
using bave::NotNull;
using bave::Seconds;
using bave::Services;

GunnerBase::GunnerBase(Services const& services, NotNull<GunKinetic*> gun, std::string_view const type) : Enemy(services, type), m_gun(gun) {}

void GunnerBase::do_tick(Seconds const dt) { m_fire_elapsed += dt; }

auto GunnerBase::make_round() -> std::unique_ptr<IWeaponRound> {
if (m_fire_elapsed < m_fire_rate) { return {}; }

m_fire_elapsed = 0s;
return m_gun->fire(get_muzzle_position());
}

auto GunnerBase::get_muzzle_position() const -> glm::vec2 {
auto ret = m_sprite.transform.position;
ret.x -= m_sprite.get_size().x;
return ret;
}
} // namespace spaced::enemy
21 changes: 21 additions & 0 deletions src/spaced/spaced/game/enemies/gunner_base.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once
#include <spaced/game/enemy.hpp>
#include <spaced/game/weapons/gun_kinetic.hpp>

namespace spaced::enemy {
class GunnerBase : public Enemy {
public:
explicit GunnerBase(bave::Services const& services, bave::NotNull<GunKinetic*> gun, std::string_view type);

protected:
auto make_round() -> std::unique_ptr<IWeaponRound> final;
void do_tick(bave::Seconds dt) override;

[[nodiscard]] auto get_muzzle_position() const -> glm::vec2;

bave::NotNull<GunKinetic*> m_gun;
bave::Seconds m_fire_rate{3.3s};

bave::Seconds m_fire_elapsed{};
};
} // namespace spaced::enemy
37 changes: 37 additions & 0 deletions src/spaced/spaced/game/enemies/trooper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <bave/core/random.hpp>
#include <bave/services/resources.hpp>
#include <spaced/game/enemies/trooper.hpp>

namespace spaced::enemy {
using bave::NotNull;
using bave::random_in_range;
using bave::Resources;
using bave::Seconds;
using bave::Services;
using bave::Texture;

namespace {
constexpr auto at_end(float const y, float const y_min, float const y_max) { return y_min > y || y > y_max; }
} // namespace

Trooper::Trooper(Services const& services, NotNull<GunKinetic*> gun) : GunnerBase(services, gun, "Trooper") {
if (auto texture = services.get<Resources>().get<Texture>("images/ship_trooper.png")) {
m_sprite.set_size(texture->get_size());
m_sprite.set_texture(std::move(texture));
}

m_direction = random_in_range(0, 1) == 0 ? 1.0f : -1.0f;

health = 3.0f;
speed = 150.0f;
}

void Trooper::do_tick(Seconds const dt) {
GunnerBase::do_tick(dt);

m_sprite.transform.position.y += m_direction * m_y_speed * dt.count();
auto const y_min = get_layout().play_area.rb.y + m_sprite.get_size().y;
auto const y_max = get_layout().play_area.lt.y - m_sprite.get_size().y;
if (at_end(m_sprite.transform.position.y, y_min, y_max)) { m_direction = -m_direction; }
}
} // namespace spaced::enemy
16 changes: 16 additions & 0 deletions src/spaced/spaced/game/enemies/trooper.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once
#include <spaced/game/enemies/gunner_base.hpp>
#include <spaced/game/weapons/gun_kinetic.hpp>

namespace spaced::enemy {
class Trooper : public GunnerBase {
public:
explicit Trooper(bave::Services const& services, bave::NotNull<GunKinetic*> gun);

private:
void do_tick(bave::Seconds dt) final;

float m_y_speed{150.0f};
float m_direction{1.0f};
};
} // namespace spaced::enemy
18 changes: 15 additions & 3 deletions src/spaced/spaced/game/enemy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,24 @@ void Enemy::force_death() {
}

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};
auto position = m_sprite.transform.position;
position.y += 0.5f * m_sprite.get_shape().size.y + 20.0f;
m_health_bar.set_position(position);
m_health_bar.set_size({m_sprite.get_shape().size.x, 10.0f});
m_health_bar.set_progress(health.get_hit_points() / health.get_total_hit_points());
}

auto Enemy::tick(Seconds const dt) -> std::unique_ptr<IWeaponRound> {
do_tick(dt);

m_sprite.transform.position.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();

return make_round();
}

void Enemy::draw(Shader& shader) const {
m_sprite.draw(shader);
m_health_bar.draw(shader);
Expand Down
7 changes: 6 additions & 1 deletion src/spaced/spaced/game/enemy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <bave/ui/progress_bar.hpp>
#include <spaced/game/damageable.hpp>
#include <spaced/game/health.hpp>
#include <spaced/game/weapon_round.hpp>
#include <spaced/services/layout.hpp>

namespace spaced {
Expand All @@ -24,7 +25,7 @@ class Enemy : public IDamageable, public bave::IDrawable {
[[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) = 0;
auto tick(bave::Seconds dt) -> std::unique_ptr<IWeaponRound>;
void draw(bave::Shader& shader) const override;

void setup(glm::vec2 max_size, float y_position);
Expand All @@ -38,11 +39,15 @@ class Enemy : public IDamageable, public bave::IDrawable {

Health health{};
std::int64_t points{10};
float speed{100.0f};

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

protected:
virtual void do_tick(bave::Seconds /*dt*/) {}
virtual auto make_round() -> std::unique_ptr<IWeaponRound> { return {}; }

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

Expand Down
2 changes: 1 addition & 1 deletion src/spaced/spaced/game/hud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ void Hud::create_lives(Services const& services) {
m_lives_icon = sprite.get();
m_lives_icon->sprite.set_size(glm::vec2{20.0f});
auto const& resources = services.get<Resources>();
if (auto const texture = resources.get<Texture>("images/player_ship_icon.png")) {
if (auto const texture = resources.get<Texture>("images/icon_player.png")) {
m_lives_icon->sprite.set_texture(texture);
m_lives_icon->sprite.set_size(texture->get_size());
}
Expand Down
Loading