Adding some sound effects
This commit is contained in:
parent
cb79147e50
commit
6ad1272d7d
14 changed files with 72 additions and 44 deletions
BIN
Resources/sounds/gun/mach_pew.ogg
Normal file
BIN
Resources/sounds/gun/mach_pew.ogg
Normal file
Binary file not shown.
BIN
Resources/sounds/gun/reload.ogg
Normal file
BIN
Resources/sounds/gun/reload.ogg
Normal file
Binary file not shown.
|
|
@ -6,5 +6,9 @@
|
|||
<!-- Pistol Sounds -->
|
||||
<sound id="gun/pistol/shoot" spatial="true" path="sounds/gun/small_pew.ogg"/>
|
||||
|
||||
<!-- Machine Gun Sounds -->
|
||||
<sound id="gun/machine/shoot" spatial="true" path="sounds/gun/mach_pew.ogg"/>
|
||||
|
||||
<!-- Generic Sounds -->
|
||||
<sound id="gun/generic/shoot" spatial="true" path="sounds/gun/small_pew.ogg"/>
|
||||
<sound id="gun/generic/reload" spatial="true" path="sounds/gun/reload.ogg"/>
|
||||
|
|
|
|||
|
|
@ -5,17 +5,17 @@
|
|||
#include <unordered_map>
|
||||
#include <SDL_timer.h>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
|
||||
#include "gameplay/entity.h"
|
||||
#include "gameplay/weapons/weapon.h"
|
||||
#include "utility/mousestate.h"
|
||||
|
||||
#include <utility/component.h>
|
||||
|
||||
class AI;
|
||||
class Weapon;
|
||||
class ISceneContext;
|
||||
|
||||
// TODO: Finish weapon cycling code and add default weapon to every actor
|
||||
// TODO: Add ammo system, then work on some basic UI design
|
||||
|
||||
class GameActor : public Entity
|
||||
|
|
@ -25,11 +25,12 @@ public:
|
|||
~GameActor();
|
||||
|
||||
void addComponent(std::unique_ptr<Component> component);
|
||||
void pickupWeapon(std::shared_ptr<Weapon> weapon);
|
||||
void pickupWeapon(std::unique_ptr<Weapon> weapon);
|
||||
void update(double deltaTime) override;
|
||||
void draw() override;
|
||||
|
||||
const std::shared_ptr<Weapon> getHeldWeapon() const;
|
||||
Weapon* getHeldWeapon() const;
|
||||
std::span<Weapon*> getAllWeapons();
|
||||
|
||||
void setRotation(const float& rotation) override;
|
||||
|
||||
|
|
@ -49,11 +50,9 @@ public:
|
|||
void cycleWeapons(const MouseState&);
|
||||
void followMouse(const MouseState&);
|
||||
private:
|
||||
using component_vector_t = std::vector<std::unique_ptr<Component>>;
|
||||
using weapon_vector_t = std::vector<std::shared_ptr<Weapon>>;
|
||||
|
||||
component_vector_t components;
|
||||
weapon_vector_t weapons;
|
||||
std::vector<std::unique_ptr<Component>> components;
|
||||
std::vector<std::unique_ptr<Weapon>> weapons;
|
||||
std::vector<Weapon*> weaponCache;
|
||||
size_t currentWeaponIndex = 0;
|
||||
|
||||
ISceneContext* sceneContext;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class WeaponScript;
|
|||
struct PhysicsComponent;
|
||||
struct WeaponData;
|
||||
|
||||
class Weapon : public Entity, public std::enable_shared_from_this<Weapon>
|
||||
class Weapon : public Entity
|
||||
{
|
||||
public:
|
||||
Weapon(const WeaponData* data, const unsigned weaponShaderID, const unsigned bulletShaderID, ResourceManager* resourceManager);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ public:
|
|||
private:
|
||||
struct AudioSource {
|
||||
ALuint source;
|
||||
ALuint buffer;
|
||||
bool inUse;
|
||||
int priority;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public:
|
|||
const unsigned loadSoundEffect (const std::string& id);
|
||||
std::unique_ptr<AIScript> loadAIScript (const std::string& path);
|
||||
std::unique_ptr<WeaponScript> loadWeaponScript (const std::string& path);
|
||||
std::shared_ptr<Weapon> loadWeapon (const std::string& name, const unsigned weaponShaderID, const unsigned bulletShaderID);
|
||||
std::unique_ptr<Weapon> loadWeapon (const std::string& name, const unsigned weaponShaderID, const unsigned bulletShaderID);
|
||||
std::shared_ptr<AnimationSet> loadAnimationSet (const std::string& name, int entityid = 0);
|
||||
|
||||
const unsigned loadShader (const std::string& name, const std::string& vertexPath, const std::string& fragPath);
|
||||
|
|
@ -62,7 +62,7 @@ private:
|
|||
std::unordered_map<unsigned, Shader*> shaderIDs;
|
||||
std::unordered_map<std::string, std::unique_ptr<SoundEffect>> sounds;
|
||||
std::unordered_map<std::string, std::unique_ptr<Sprite>> sprites;
|
||||
std::unordered_map<std::string, std::shared_ptr<Weapon>> weapons;
|
||||
//std::unordered_map<std::string, std::unique_ptr<Weapon>> weapons;
|
||||
//std::unordered_map<std::string, std::string> scripts;
|
||||
std::unordered_map<std::string, std::unique_ptr<Background>> backgrounds;
|
||||
std::unordered_map<std::string, std::shared_ptr<TileSetData>> tileSets;
|
||||
|
|
|
|||
|
|
@ -16,18 +16,24 @@ void GameActor::addComponent(std::unique_ptr<Component> component)
|
|||
components.push_back(std::move(component));
|
||||
}
|
||||
|
||||
const std::shared_ptr<Weapon> GameActor::getHeldWeapon() const
|
||||
Weapon* GameActor::getHeldWeapon() const
|
||||
{
|
||||
return (weapons.empty() || currentWeaponIndex >= weapons.size()) ? nullptr : weapons[currentWeaponIndex];
|
||||
return (weapons.empty() || currentWeaponIndex >= weapons.size()) ? nullptr : weapons[currentWeaponIndex].get();
|
||||
}
|
||||
|
||||
void GameActor::pickupWeapon(std::shared_ptr<Weapon> weapon)
|
||||
std::span<Weapon*> GameActor::getAllWeapons()
|
||||
{
|
||||
return weaponCache;
|
||||
}
|
||||
|
||||
void GameActor::pickupWeapon(std::unique_ptr<Weapon> weapon)
|
||||
{
|
||||
weapon->setWielder(this);
|
||||
if (auto eventManager = sceneContext->getEventManager().lock()) {
|
||||
weapon->hookEventManager(eventManager);
|
||||
}
|
||||
weapons.push_back(weapon);
|
||||
weaponCache.push_back(weapon.get());
|
||||
weapons.push_back(std::move(weapon));
|
||||
// wield the newly picked up weapon.
|
||||
getHeldWeapon()->putaway();
|
||||
currentWeaponIndex = weapons.size() - 1;
|
||||
|
|
@ -40,7 +46,7 @@ void GameActor::setRotation(const float& rotation)
|
|||
if (auto eventManager = sceneContext->getEventManager().lock()) {
|
||||
Direction newDir = getDirectionFromRotation(rotation);
|
||||
if (getDirectionFromRotation(this->rotation) != newDir)
|
||||
eventManager->notify<DirectionChangeEvent>((DirectionChangeEvent){ entityid, newDir });
|
||||
eventManager->notify<DirectionChangeEvent>({ entityid, newDir });
|
||||
}
|
||||
}
|
||||
this->rotation = rotation;
|
||||
|
|
@ -59,14 +65,14 @@ void GameActor::update(double deltaTime)
|
|||
if (isMoving && !wasMoving)
|
||||
{
|
||||
if (auto event = sceneContext->getEventManager().lock()) {
|
||||
event->notify<EntityMoveEvent>((EntityMoveEvent){ entityid });
|
||||
event->notify<EntityMoveEvent>({ entityid });
|
||||
}
|
||||
wasMoving = true;
|
||||
}
|
||||
else if (!isMoving && wasMoving)
|
||||
{
|
||||
if (auto event = sceneContext->getEventManager().lock()) {
|
||||
event->notify<EntityStopEvent>((EntityStopEvent){ entityid });
|
||||
event->notify<EntityStopEvent>({ entityid });
|
||||
}
|
||||
wasMoving = false;
|
||||
}
|
||||
|
|
@ -95,12 +101,12 @@ void GameActor::moveRight(){ if (physics) physics->rigidBody.applyForce(glm::vec
|
|||
|
||||
// top-down shooter mode controls
|
||||
void GameActor::fireWeapon()const {
|
||||
if (auto& weapon = getHeldWeapon()) {
|
||||
if (auto weapon = getHeldWeapon()) {
|
||||
if (weapon->shoot()) {
|
||||
if (sceneContext->getPlayerID() == entityid) {
|
||||
if (auto gEvent = sceneContext->getGlobalEventManager().lock()) {
|
||||
gEvent->notify<ScreenShakeEvent>((ScreenShakeEvent){0.01f, 0.8f});
|
||||
gEvent->notify<ScreenBlurEvent>((ScreenBlurEvent){1.f, 0.8f});
|
||||
gEvent->notify<ScreenShakeEvent>({0.01f, 0.8f});
|
||||
gEvent->notify<ScreenBlurEvent>({1.f, 0.8f});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -134,7 +140,7 @@ void GameActor::followMouse(const MouseState& mouse_state)
|
|||
float newRotation = glm::degrees(glm::atan(direction.y, direction.x));
|
||||
if (getDirectionFromRotation(rotation) != getDirectionFromRotation(newRotation)) {
|
||||
if (auto event = sceneContext->getEventManager().lock()) {
|
||||
event->notify<DirectionChangeEvent>((DirectionChangeEvent){ entityid, getDirectionFromRotation(newRotation) });
|
||||
event->notify<DirectionChangeEvent>({ entityid, getDirectionFromRotation(newRotation) });
|
||||
}
|
||||
}
|
||||
//setRotation(glm::degrees(glm::atan(direction.y, direction.x)));
|
||||
|
|
|
|||
|
|
@ -92,8 +92,8 @@ void Scene::loadDebugShooterScene()
|
|||
auto defaultWeapon = resourceManager->loadWeapon("gun/pistol", weaponShader, bubbleShader);
|
||||
auto entityWeapon = resourceManager->loadWeapon(entityData.weapon, weaponShader, bubbleShader);
|
||||
|
||||
entity->pickupWeapon(defaultWeapon);
|
||||
entity->pickupWeapon(entityWeapon);
|
||||
entity->pickupWeapon(std::move(defaultWeapon));
|
||||
entity->pickupWeapon(std::move(entityWeapon));
|
||||
entity->setPosition(glm::vec3(entityData.x * mapData->tileSize, entityData.y * mapData->tileSize, 0.f));
|
||||
entity->setScale(glm::vec3(mapData->tileSize, mapData->tileSize, 1.f));
|
||||
|
||||
|
|
@ -166,9 +166,12 @@ void Scene::render(std::shared_ptr<Renderer> renderer)
|
|||
//e->draw();
|
||||
renderer->addDrawable(RenderLayer::GameObjects, e.get());
|
||||
if (e->getHeldWeapon()) {
|
||||
renderer->addDrawable(RenderLayer::GameObjects, e->getHeldWeapon().get());
|
||||
for (const auto& bullet : e->getHeldWeapon()->getBulletManager()->getBullets()) {
|
||||
renderer->addDrawable(RenderLayer::GameObjects, bullet.get());
|
||||
renderer->addDrawable(RenderLayer::GameObjects, e->getHeldWeapon());
|
||||
const auto& weapons = e->getAllWeapons();
|
||||
for (auto& w : weapons) {
|
||||
for (auto b : w->getBulletManager()->getBullets()) {
|
||||
renderer->addDrawable(RenderLayer::GameObjects, b.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -222,7 +225,7 @@ void Scene::hookSceneEvents()
|
|||
GameActor* shooter = self->getGameActorByID(e.ownerID);
|
||||
GameActor* target = self->getGameActorByID(e.victimID);
|
||||
if (shooter && target)
|
||||
if (auto& weapon = shooter->getHeldWeapon())
|
||||
if (auto weapon = shooter->getHeldWeapon())
|
||||
weapon->onHitCallback(target, e.bullet.get(), e.normal);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -119,9 +119,9 @@ void Weapon::hookEventManager(std::weak_ptr<EventManager> eventManager)
|
|||
}
|
||||
|
||||
if (auto event = this->eventManager.lock()) {
|
||||
std::weak_ptr<Weapon> selfWeak = shared_from_this();
|
||||
event->subscribe<AnimationFinishedEvent>([selfWeak](const AnimationFinishedEvent& e) {
|
||||
if (auto self = selfWeak.lock()) {
|
||||
auto self = this;
|
||||
event->subscribe<AnimationFinishedEvent>([self](const AnimationFinishedEvent& e) {
|
||||
if (self) {
|
||||
if (e.entityid == self->entityid && e.animType == "reload")
|
||||
{
|
||||
if (self->reloading)
|
||||
|
|
|
|||
|
|
@ -28,15 +28,25 @@ void AudioEngine::hookSceneManager(std::weak_ptr<EventManager> _events)
|
|||
sceneEventManager = _events;
|
||||
if (auto weak = sceneEventManager.lock()) {
|
||||
std::weak_ptr<AudioEngine> weakSelf = shared_from_this();
|
||||
weak->subscribe<EntityFireEvent>([weakSelf](const EntityFireEvent& e){
|
||||
auto play_sound = [weakSelf](const std::string& id, int priority, const std::optional<glm::vec3>& pos = std::nullopt) {
|
||||
if (auto self = weakSelf.lock()) {
|
||||
if (auto res = self->resourceManager.lock()) {
|
||||
auto buf = res->loadSoundEffect(e.weaponType + "/shoot");
|
||||
auto buf = res->loadSoundEffect(id);
|
||||
if (buf != 0) {
|
||||
self->soundManager->playSound(buf, 10, e.firePosition);
|
||||
if (pos != std::nullopt)
|
||||
self->soundManager->playSound(buf, priority, pos.value());
|
||||
else
|
||||
self->soundManager->playSound(buf, priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
weak->subscribe<EntityFireEvent>([weakSelf,play_sound](const EntityFireEvent& e){
|
||||
play_sound(e.weaponType + "/shoot", 10, e.firePosition);
|
||||
});
|
||||
weak->subscribe<EntityReloadEvent>([weakSelf,play_sound](const EntityReloadEvent& e) {
|
||||
play_sound(e.weaponType + "/reload", 9, e.position);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ SoundManager::SoundManager()
|
|||
s.priority = 0;
|
||||
alSourcef(s.source, AL_REFERENCE_DISTANCE, 1.0f);
|
||||
alSourcef(s.source, AL_MAX_DISTANCE, 10000.f);
|
||||
alSourcef(s.source, AL_ROLLOFF_FACTOR, 1.0f);
|
||||
alSourcef(s.source, AL_ROLLOFF_FACTOR, 0.3f);
|
||||
}
|
||||
alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ void SoundManager::playSound(ALuint buffer, int priority, const glm::vec3& pos)
|
|||
if (!sources[ring].inUse) {
|
||||
sources[ring].inUse = true;
|
||||
sources[ring].priority = priority;
|
||||
sources[ring].buffer = buffer;
|
||||
alSourcei(sources[ring].source, AL_BUFFER, buffer);
|
||||
if (pos != glm::vec3(0)) {
|
||||
//alSourcei(sources[ring].source, AL_SOURCE_RELATIVE, 1);
|
||||
|
|
@ -40,6 +41,7 @@ void SoundManager::playSound(ALuint buffer, int priority, const glm::vec3& pos)
|
|||
if (!sources[ring].inUse) {
|
||||
sources[ring].inUse = true;
|
||||
sources[ring].priority = priority;
|
||||
sources[ring].buffer = buffer;
|
||||
alSourcei(sources[ring].source, AL_BUFFER, buffer);
|
||||
if (pos != glm::vec3(0)) {
|
||||
//alSourcei(sources[ring].source, AL_SOURCE_RELATIVE, 1);
|
||||
|
|
@ -48,12 +50,12 @@ void SoundManager::playSound(ALuint buffer, int priority, const glm::vec3& pos)
|
|||
//alSourcei(sources[ring].source, AL_SOURCE_RELATIVE, 0);
|
||||
}
|
||||
alSourcePlay(sources[ring].source);
|
||||
lastUsed = ring;
|
||||
lastUsed = nextIndex(ring);
|
||||
return;
|
||||
}
|
||||
if (sources[ring].priority <= priority) {
|
||||
if (sources[ring].priority > priority || (sources[ring].buffer != buffer && sources[ring].priority == priority)) {
|
||||
if (nextBest) {
|
||||
if (nextBest->priority > sources[ring].priority) {
|
||||
if (nextBest->priority >= sources[ring].priority) {
|
||||
nextBest = &sources[ring];
|
||||
secIndex = ring;
|
||||
}
|
||||
|
|
@ -65,7 +67,9 @@ void SoundManager::playSound(ALuint buffer, int priority, const glm::vec3& pos)
|
|||
}
|
||||
if (nextBest) {
|
||||
nextBest->priority = priority;
|
||||
alSourcei(nextBest->source, AL_BUFFER, 0);
|
||||
alSourcei(nextBest->source, AL_BUFFER, buffer);
|
||||
nextBest->buffer = buffer;
|
||||
if (pos != glm::vec3(0)) {
|
||||
//alSourcei(nextBest->source, AL_SOURCE_RELATIVE, 1);
|
||||
alSourcefv(nextBest->source, AL_POSITION, glm::value_ptr(pos));
|
||||
|
|
@ -86,6 +90,7 @@ void SoundManager::pollSources()
|
|||
alGetSourcei(s.source, AL_SOURCE_STATE, &state);
|
||||
if (state == AL_STOPPED) {
|
||||
s.inUse = false;
|
||||
s.buffer = 0;
|
||||
alSourcei(s.source, AL_BUFFER, 0);
|
||||
}
|
||||
//else if (state != AL_PLAYING)
|
||||
|
|
|
|||
|
|
@ -78,17 +78,17 @@ Background* ResourceManager::loadBackground(const std::string& path)
|
|||
|
||||
// We attach our script after we create our weapon because we are passing a reference to the weapon into the script and we don't want to pass an
|
||||
// incomplete reference to our script.
|
||||
std::shared_ptr<Weapon> ResourceManager::loadWeapon(const std::string& id, const unsigned weaponShaderID, const unsigned bulletShaderID)
|
||||
std::unique_ptr<Weapon> ResourceManager::loadWeapon(const std::string& id, const unsigned weaponShaderID, const unsigned bulletShaderID)
|
||||
{
|
||||
const WeaponData* data = xmlLoader->getWeaponData(id);
|
||||
if (!data) {
|
||||
LOG(ERROR, "Could not load weapon id '{}', falling back to pistol", id);
|
||||
data = xmlLoader->getWeaponData("gun/pistol");// using this as a fallback for now
|
||||
}
|
||||
auto weapon = std::make_shared<Weapon>(data, weaponShaderID, bulletShaderID, this);
|
||||
auto weapon = std::make_unique<Weapon>(data, weaponShaderID, bulletShaderID, this);
|
||||
if (!data->script.empty())
|
||||
weapon->attachScript(loadWeaponScript(data->script));
|
||||
return weapon;
|
||||
return std::move(weapon);
|
||||
}
|
||||
|
||||
const unsigned ResourceManager::loadSoundEffect(const std::string& id)
|
||||
|
|
@ -139,7 +139,6 @@ void ResourceManager::clearResources()
|
|||
sprites.clear();
|
||||
shaders.clear();
|
||||
shaderIDs.clear();
|
||||
weapons.clear();
|
||||
tileSets.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
1
compile_flags.txt
Normal file
1
compile_flags.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
-std=c++20
|
||||
Loading…
Add table
Reference in a new issue