Skip to content

Commit 4557121

Browse files
authored
Audio framework. (#32)
* Add audio service. * Groundwork for weapon fire and enemy death SFX. * Fix Android CI.
1 parent 9975f47 commit 4557121

24 files changed

+182
-45
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@ jobs:
5757
tar xvzf jdk-17_linux-x64_bin.tar.gz -C /opt
5858
- name: build
5959
run: |
60-
export JAVA_HOME=/opt/jdk-17.0.10
60+
export JAVA_HOME=$(find /opt -name "jdk-17.*")
6161
cd src/android
6262
./gradlew assembleDebug

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ include(FetchContent)
1111
FetchContent_Declare(
1212
bave
1313
GIT_REPOSITORY https://github.com/karnkaul/bave
14-
GIT_TAG 8717d1eafd2ac581c7b90fa3af384eb66cd7896a # v0.4.8
14+
GIT_TAG ff3978f8431649007d3309db513d3de3e72fe823 # v0.4.9
1515
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/bave"
1616
)
1717

assets/sfx/bubble.wav

26 KB
Binary file not shown.

assets/worlds/playground.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
],
1616
"spawn_rate": 2,
1717
"initial_health": 2,
18-
"death_emitter": "particles/explode.json"
18+
"death_emitter": "particles/explode.json",
19+
"death_sfx": [
20+
"sfx/bubble.wav"
21+
]
1922
}
2023
]
2124
}

src/spaced/spaced/game/asset_list.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ auto AssetList::add_particle_emitter(std::string uri) -> AssetList& {
3131
return *this;
3232
}
3333

34+
auto AssetList::add_audio_clip(std::string uri) -> AssetList& {
35+
if (uri.empty()) { return *this; }
36+
m_audio_clips.insert(std::move(uri));
37+
return *this;
38+
}
39+
3440
auto AssetList::read_world_spec(std::string_view const uri) -> WorldSpec {
3541
if (uri.empty()) { return {}; }
3642

@@ -51,6 +57,7 @@ auto AssetList::read_world_spec(std::string_view const uri) -> WorldSpec {
5157

5258
for (auto const& enemy_factory : json["enemy_factories"].array_view()) {
5359
add_particle_emitter(enemy_factory["death_emitter"].as<std::string>());
60+
for (auto const& death_sfx : enemy_factory["death_sfx"].array_view()) { add_audio_clip(death_sfx.as<std::string>()); }
5461
ret.enemy_factories.push_back(enemy_factory);
5562
}
5663

@@ -70,6 +77,7 @@ auto AssetList::build_stage_0(AssetLoader& asset_loader) const -> AsyncExec::Sta
7077
auto ret = AsyncExec::Stage{};
7178
for (auto const& texture : m_textures) { ret.push_back(asset_loader.make_load_texture(texture.uri, texture.mip_map)); }
7279
for (auto const& font : m_fonts) { ret.push_back(asset_loader.make_load_font(font)); }
80+
for (auto const& audio_clip : m_audio_clips) { ret.push_back(asset_loader.make_load_audio_clip(audio_clip)); }
7381
return ret;
7482
}
7583

src/spaced/spaced/game/asset_list.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class AssetList {
1616
auto add_texture(std::string uri, bool mip_map = false) -> AssetList&;
1717
auto add_font(std::string uri) -> AssetList&;
1818
auto add_particle_emitter(std::string uri) -> AssetList&;
19+
auto add_audio_clip(std::string uri) -> AssetList&;
1920

2021
auto read_world_spec(std::string_view uri) -> WorldSpec;
2122

@@ -40,5 +41,6 @@ class AssetList {
4041
std::set<Tex> m_textures{};
4142
std::set<std::string> m_fonts{};
4243
std::set<std::string> m_emitters{};
44+
std::set<std::string> m_audio_clips{};
4345
};
4446
} // namespace spaced

src/spaced/spaced/game/asset_loader.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ auto AssetLoader::make_load_particle_emitter(std::string uri, bool const reload)
5353
return make_load_task(std::move(uri), reload, load);
5454
}
5555

56+
auto AssetLoader::make_load_audio_clip(std::string uri, bool const reload) -> LoadTask {
57+
auto const load = [](Loader const& loader, std::string_view const uri) { return loader.load_audio_clip(uri); };
58+
return make_load_task(std::move(uri), reload, load);
59+
}
60+
5661
template <typename FuncT>
5762
auto AssetLoader::make_load_task(std::string uri, bool reload, FuncT load) const -> LoadTask {
5863
return [impl = m_impl, uri = std::move(uri), reload, load] {

src/spaced/spaced/game/asset_loader.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class AssetLoader {
1616
[[nodiscard]] auto make_load_texture(std::string uri, bool mip_map = false, bool reload = false) -> LoadTask;
1717
[[nodiscard]] auto make_load_texture_atlas(std::string uri, bool mip_map = false, bool reload = false) -> LoadTask;
1818
[[nodiscard]] auto make_load_particle_emitter(std::string uri, bool reload = false) -> LoadTask;
19+
[[nodiscard]] auto make_load_audio_clip(std::string uri, bool reload = false) -> LoadTask;
1920

2021
private:
2122
template <typename FuncT>

src/spaced/spaced/game/enemies/basic_creep_factory.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@ using bave::random_in_range;
1313
using bave::Seconds;
1414

1515
BasicCreepFactory::BasicCreepFactory(NotNull<Services const*> services, NotNull<IEnemyDeathListener*> listener, dj::Json const& json)
16-
: m_services(services), m_listener(listener) {
16+
: IEnemyFactory(services), m_listener(listener) {
1717
for (auto const& tint : json["tints"].array_view()) { tints.push_back(tint.as<std::string>()); }
1818
if (auto const in_death_emitter = services->get<Resources>().get<ParticleEmitter>(json["death_emitter"].as_string())) { death_emitter = *in_death_emitter; }
1919
spawn_rate = Seconds{json["spawn_rate"].as<float>(spawn_rate.count())};
2020
initial_health = json["initial_health"].as<float>(initial_health);
21+
for (auto const& death_sfx : json["death_sfx"].array_view()) { m_death_sfx.push_back(death_sfx.as<std::string>()); }
2122
}
2223

2324
auto BasicCreepFactory::spawn_enemy() -> std::unique_ptr<Enemy> {
24-
auto ret = std::make_unique<Creep>(*m_services, m_listener);
25+
auto ret = std::make_unique<Creep>(get_services(), m_listener);
2526
if (!tints.empty()) {
26-
auto const& rgbas = m_services->get<Styles>().rgbas;
27+
auto const& rgbas = get_services().get<Styles>().rgbas;
2728
auto const tint_index = random_in_range(std::size_t{}, tints.size() - 1);
2829
ret->shape.tint = rgbas[tints.at(tint_index)];
2930
ret->health = initial_health;

src/spaced/spaced/game/enemies/basic_creep_factory.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ class BasicCreepFactory : public IEnemyFactory {
2323
private:
2424
void do_inspect() final;
2525

26-
bave::NotNull<Services const*> m_services;
2726
bave::NotNull<IEnemyDeathListener*> m_listener;
2827
bave::Seconds m_elapsed{};
2928
};

0 commit comments

Comments
 (0)