Working sound system and most enemies have a sound effect. This will make it easier to add sounds now.

master
Zed A. Shaw 2 weeks ago
parent 83df9ff03b
commit 20cbc3a21c
  1. 5
      assets/config.json
  2. 15
      assets/enemies.json
  3. BIN
      assets/monster-16.ogg
  4. BIN
      assets/sword.1.ogg
  5. 2
      components.cpp
  6. 5
      components.hpp
  7. 2
      main.cpp
  8. 2
      meson.build
  9. 54
      sound.cpp
  10. 22
      sound.hpp
  11. 9
      systems.cpp
  12. 15
      tests/sound.cpp

@ -1,4 +1,9 @@
{
"sounds": {
"sword_1": "assets/sword.1.ogg",
"monster_16": "assets/monster-16.ogg",
"monster_1": "assets/monster-1.ogg"
},
"sprites": {
"armored_knight": "assets/armored_knight_1-256.png",
"sword": "assets/cinqueda_1-512.png",

@ -23,7 +23,8 @@
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
{"_type": "EnemyConfig", "hearing_distance": 5},
{"_type": "Animation", "scale": 0.2, "simple": true, "frames": 10, "speed": 0.3},
{"_type": "Sprite", "name": "armored_knight"}
{"_type": "Sprite", "name": "armored_knight"},
{"_type": "Sound", "attack": "monster_1", "death": "monster_16"}
]
},
"AXE_RANGER": {
@ -36,7 +37,8 @@
{"_type": "Motion", "dx": 0, "dy": 0, "random": true},
{"_type": "EnemyConfig", "hearing_distance": 5},
{"_type": "Sprite", "name": "axe_ranger"},
{"_type": "Animation", "scale": 0.2, "simple": false, "frames": 10, "speed": 0.6}
{"_type": "Animation", "scale": 0.2, "simple": false, "frames": 10, "speed": 0.6},
{"_type": "Sound", "attack": "sword_1", "death": "monster_16"}
]
},
"EVIL_EYE": {
@ -49,7 +51,8 @@
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
{"_type": "EnemyConfig", "hearing_distance": 5},
{"_type": "Sprite", "name": "evil_eye"},
{"_type": "Animation", "scale": 0.2, "simple": false, "frames": 10, "speed": 0.3}
{"_type": "Animation", "scale": 0.2, "simple": false, "frames": 10, "speed": 0.3},
{"_type": "Sound", "attack": "monster_1", "death": "monster_16"}
]
},
"RAT_GIANT": {
@ -62,7 +65,8 @@
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
{"_type": "EnemyConfig", "hearing_distance": 10},
{"_type": "Animation", "scale": 0.2, "simple": true, "frames": 10, "speed": 1.0},
{"_type": "Sprite", "name": "rat_with_sword"}
{"_type": "Sprite", "name": "rat_with_sword"},
{"_type": "Sound", "attack": "sword_1", "death": "monster_16"}
]
},
"SPIDER_GIANT_HAIRY": {
@ -75,7 +79,8 @@
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
{"_type": "EnemyConfig", "hearing_distance": 10},
{"_type": "Animation", "scale": 0.2, "simple": true, "frames": 10, "speed": 1.0},
{"_type": "Sprite", "name": "hairy_spider"}
{"_type": "Sprite", "name": "hairy_spider"},
{"_type": "Sound", "attack": "sword_1", "death": "monster_16"}
]
}
}

Binary file not shown.

Binary file not shown.

@ -13,6 +13,7 @@ namespace components {
ENROLL_COMPONENT(Device, config, events);
ENROLL_COMPONENT(Sprite, name);
ENROLL_COMPONENT(Animation, scale, simple, frames, speed);
ENROLL_COMPONENT(Sound, attack, death);
void configure_entity(const ComponentMap& component_map, DinkyECS::World& world, DinkyECS::Entity ent, json& data) {
for (auto &i : data) {
@ -35,6 +36,7 @@ namespace components {
components::enroll<Device>(component_map);
components::enroll<Sprite>(component_map);
components::enroll<Animation>(component_map);
components::enroll<Sound>(component_map);
}
void Animation::play() {

@ -86,6 +86,11 @@ namespace components {
string name;
};
struct Sound {
std::string attack;
std::string death;
};
struct Animation {
float scale = 0.0f;
bool simple = true;

@ -1,8 +1,10 @@
#include "gui_fsm.hpp"
#include "textures.hpp"
#include "sound.hpp"
int main() {
textures::init();
sound::init();
gui::FSM main;
main.event(gui::Event::STARTED);

@ -79,6 +79,7 @@ sources = [
'render.cpp',
'save.cpp',
'shiterator.hpp',
'sound.cpp',
'spatialmap.cpp',
'stats.cpp',
'status_ui.cpp',
@ -104,6 +105,7 @@ executable('runtests', sources + [
'tests/map.cpp',
'tests/matrix.cpp',
'tests/pathing.cpp',
'tests/sound.cpp',
'tests/spatialmap.cpp',
'tests/textures.cpp',
'tests/tilemap.cpp',

@ -0,0 +1,54 @@
#include "sound.hpp"
#include "dbc.hpp"
#include <fmt/core.h>
#include "config.hpp"
namespace sound {
static SoundManager SMGR;
static bool initialized = false;
using namespace fmt;
using std::make_shared;
namespace fs = std::filesystem;
void init() {
if(!initialized) {
Config assets("assets/config.json");
for(auto& el : assets["sounds"].items()) {
load(el.key(), el.value());
}
initialized = true;
}
}
void load(const std::string name, const std::string sound_path) {
dbc::check(fs::exists(sound_path), fmt::format("sound file {} does not exist", sound_path));
// create the buffer and keep in the buffer map
auto buffer = make_shared<sf::SoundBuffer>(sound_path);
// set it on the sound and keep in the sound map
auto sound = make_shared<sf::Sound>(*buffer);
sound->setRelativeToListener(false);
sound->setPosition({0.0f, 0.0f, 1.0f});
SMGR.sounds.try_emplace(name, buffer, sound);
}
void play(const std::string name) {
dbc::check(initialized, "You need to call sound::init() first");
dbc::check(SMGR.sounds.contains(name), fmt::format("sound {} is not loaded in map", name));
// get the sound from the sound map
auto pair = SMGR.sounds.at(name);
// play it
pair.sound->play();
}
void play_at(const std::string name, float x, float y, float z) {
dbc::check(initialized, "You need to call sound::init() first");
auto pair = SMGR.sounds.at(name);
pair.sound->setPosition({x, y, z});
pair.sound->play();
}
}

@ -0,0 +1,22 @@
#pragma once
#include <string>
#include <filesystem>
#include <memory>
#include <unordered_map>
#include <SFML/Audio.hpp>
namespace sound {
struct SoundPair {
std::shared_ptr<sf::SoundBuffer> buffer;
std::shared_ptr<sf::Sound> sound;
};
struct SoundManager {
std::unordered_map<std::string, SoundPair> sounds;
};
void init();
void load(const std::string name, const std::string path);
void play(const std::string name);
void play_at(const std::string name, float x, float y, float z);
}

@ -8,6 +8,7 @@
#include "lights.hpp"
#include "inventory.hpp"
#include "events.hpp"
#include "sound.hpp"
using std::string;
using namespace fmt;
@ -133,6 +134,10 @@ void System::death(GameLevel &level, components::ComponentMap& components) {
world.remove<EnemyConfig>(ent);
world.remove<Animation>(ent);
if(auto snd = world.get_if<Sound>(ent)) {
sound::play(snd->death);
}
auto entity_data = config.items["GRAVE_STONE"];
components::configure_entity(components, world, ent, entity_data["components"]);
if(entity_data["inventory_count"] > 0) {
@ -167,6 +172,10 @@ void System::combat(GameLevel &level) {
animation.play();
}
if(auto snd = world.get_if<Sound>(entity)) {
sound::play(snd->attack);
}
world.send<Events::GUI>(Events::GUI::COMBAT, entity, result);
}
}

@ -0,0 +1,15 @@
#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include <string>
#include "sound.hpp"
#include "levelmanager.hpp"
using namespace fmt;
TEST_CASE("test sound manager", "[sound]") {
sound::init();
sound::play("sword_1");
sound::play_at("sword_1", 0.1, 0.1, 0.1);
}
Loading…
Cancel
Save