Working sound system and most enemies have a sound effect. This will make it easier to add sounds now.
This commit is contained in:
parent
83df9ff03b
commit
20cbc3a21c
12 changed files with 126 additions and 5 deletions
|
@ -1,4 +1,9 @@
|
||||||
{
|
{
|
||||||
|
"sounds": {
|
||||||
|
"sword_1": "assets/sword.1.ogg",
|
||||||
|
"monster_16": "assets/monster-16.ogg",
|
||||||
|
"monster_1": "assets/monster-1.ogg"
|
||||||
|
},
|
||||||
"sprites": {
|
"sprites": {
|
||||||
"armored_knight": "assets/armored_knight_1-256.png",
|
"armored_knight": "assets/armored_knight_1-256.png",
|
||||||
"sword": "assets/cinqueda_1-512.png",
|
"sword": "assets/cinqueda_1-512.png",
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
|
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
|
||||||
{"_type": "EnemyConfig", "hearing_distance": 5},
|
{"_type": "EnemyConfig", "hearing_distance": 5},
|
||||||
{"_type": "Animation", "scale": 0.2, "simple": true, "frames": 10, "speed": 0.3},
|
{"_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": {
|
"AXE_RANGER": {
|
||||||
|
@ -36,7 +37,8 @@
|
||||||
{"_type": "Motion", "dx": 0, "dy": 0, "random": true},
|
{"_type": "Motion", "dx": 0, "dy": 0, "random": true},
|
||||||
{"_type": "EnemyConfig", "hearing_distance": 5},
|
{"_type": "EnemyConfig", "hearing_distance": 5},
|
||||||
{"_type": "Sprite", "name": "axe_ranger"},
|
{"_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": {
|
"EVIL_EYE": {
|
||||||
|
@ -49,7 +51,8 @@
|
||||||
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
|
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
|
||||||
{"_type": "EnemyConfig", "hearing_distance": 5},
|
{"_type": "EnemyConfig", "hearing_distance": 5},
|
||||||
{"_type": "Sprite", "name": "evil_eye"},
|
{"_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": {
|
"RAT_GIANT": {
|
||||||
|
@ -62,7 +65,8 @@
|
||||||
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
|
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
|
||||||
{"_type": "EnemyConfig", "hearing_distance": 10},
|
{"_type": "EnemyConfig", "hearing_distance": 10},
|
||||||
{"_type": "Animation", "scale": 0.2, "simple": true, "frames": 10, "speed": 1.0},
|
{"_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": {
|
"SPIDER_GIANT_HAIRY": {
|
||||||
|
@ -75,7 +79,8 @@
|
||||||
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
|
{"_type": "Motion", "dx": 0, "dy": 0, "random": false},
|
||||||
{"_type": "EnemyConfig", "hearing_distance": 10},
|
{"_type": "EnemyConfig", "hearing_distance": 10},
|
||||||
{"_type": "Animation", "scale": 0.2, "simple": true, "frames": 10, "speed": 1.0},
|
{"_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"}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
assets/monster-16.ogg
Normal file
BIN
assets/monster-16.ogg
Normal file
Binary file not shown.
BIN
assets/sword.1.ogg
Normal file
BIN
assets/sword.1.ogg
Normal file
Binary file not shown.
|
@ -13,6 +13,7 @@ namespace components {
|
||||||
ENROLL_COMPONENT(Device, config, events);
|
ENROLL_COMPONENT(Device, config, events);
|
||||||
ENROLL_COMPONENT(Sprite, name);
|
ENROLL_COMPONENT(Sprite, name);
|
||||||
ENROLL_COMPONENT(Animation, scale, simple, frames, speed);
|
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) {
|
void configure_entity(const ComponentMap& component_map, DinkyECS::World& world, DinkyECS::Entity ent, json& data) {
|
||||||
for (auto &i : data) {
|
for (auto &i : data) {
|
||||||
|
@ -35,6 +36,7 @@ namespace components {
|
||||||
components::enroll<Device>(component_map);
|
components::enroll<Device>(component_map);
|
||||||
components::enroll<Sprite>(component_map);
|
components::enroll<Sprite>(component_map);
|
||||||
components::enroll<Animation>(component_map);
|
components::enroll<Animation>(component_map);
|
||||||
|
components::enroll<Sound>(component_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::play() {
|
void Animation::play() {
|
||||||
|
|
|
@ -86,6 +86,11 @@ namespace components {
|
||||||
string name;
|
string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Sound {
|
||||||
|
std::string attack;
|
||||||
|
std::string death;
|
||||||
|
};
|
||||||
|
|
||||||
struct Animation {
|
struct Animation {
|
||||||
float scale = 0.0f;
|
float scale = 0.0f;
|
||||||
bool simple = true;
|
bool simple = true;
|
||||||
|
|
2
main.cpp
2
main.cpp
|
@ -1,8 +1,10 @@
|
||||||
#include "gui_fsm.hpp"
|
#include "gui_fsm.hpp"
|
||||||
#include "textures.hpp"
|
#include "textures.hpp"
|
||||||
|
#include "sound.hpp"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
textures::init();
|
textures::init();
|
||||||
|
sound::init();
|
||||||
gui::FSM main;
|
gui::FSM main;
|
||||||
main.event(gui::Event::STARTED);
|
main.event(gui::Event::STARTED);
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ sources = [
|
||||||
'render.cpp',
|
'render.cpp',
|
||||||
'save.cpp',
|
'save.cpp',
|
||||||
'shiterator.hpp',
|
'shiterator.hpp',
|
||||||
|
'sound.cpp',
|
||||||
'spatialmap.cpp',
|
'spatialmap.cpp',
|
||||||
'stats.cpp',
|
'stats.cpp',
|
||||||
'status_ui.cpp',
|
'status_ui.cpp',
|
||||||
|
@ -104,6 +105,7 @@ executable('runtests', sources + [
|
||||||
'tests/map.cpp',
|
'tests/map.cpp',
|
||||||
'tests/matrix.cpp',
|
'tests/matrix.cpp',
|
||||||
'tests/pathing.cpp',
|
'tests/pathing.cpp',
|
||||||
|
'tests/sound.cpp',
|
||||||
'tests/spatialmap.cpp',
|
'tests/spatialmap.cpp',
|
||||||
'tests/textures.cpp',
|
'tests/textures.cpp',
|
||||||
'tests/tilemap.cpp',
|
'tests/tilemap.cpp',
|
||||||
|
|
54
sound.cpp
Normal file
54
sound.cpp
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
22
sound.hpp
Normal file
22
sound.hpp
Normal file
|
@ -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 "lights.hpp"
|
||||||
#include "inventory.hpp"
|
#include "inventory.hpp"
|
||||||
#include "events.hpp"
|
#include "events.hpp"
|
||||||
|
#include "sound.hpp"
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using namespace fmt;
|
using namespace fmt;
|
||||||
|
@ -133,6 +134,10 @@ void System::death(GameLevel &level, components::ComponentMap& components) {
|
||||||
world.remove<EnemyConfig>(ent);
|
world.remove<EnemyConfig>(ent);
|
||||||
world.remove<Animation>(ent);
|
world.remove<Animation>(ent);
|
||||||
|
|
||||||
|
if(auto snd = world.get_if<Sound>(ent)) {
|
||||||
|
sound::play(snd->death);
|
||||||
|
}
|
||||||
|
|
||||||
auto entity_data = config.items["GRAVE_STONE"];
|
auto entity_data = config.items["GRAVE_STONE"];
|
||||||
components::configure_entity(components, world, ent, entity_data["components"]);
|
components::configure_entity(components, world, ent, entity_data["components"]);
|
||||||
if(entity_data["inventory_count"] > 0) {
|
if(entity_data["inventory_count"] > 0) {
|
||||||
|
@ -167,6 +172,10 @@ void System::combat(GameLevel &level) {
|
||||||
animation.play();
|
animation.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(auto snd = world.get_if<Sound>(entity)) {
|
||||||
|
sound::play(snd->attack);
|
||||||
|
}
|
||||||
|
|
||||||
world.send<Events::GUI>(Events::GUI::COMBAT, entity, result);
|
world.send<Events::GUI>(Events::GUI::COMBAT, entity, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
tests/sound.cpp
Normal file
15
tests/sound.cpp
Normal file
|
@ -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…
Add table
Add a link
Reference in a new issue