Code refactoring.

master
Vectozavr 2021-10-17 23:38:16 +07:00
parent a499b4503d
commit dd5a9f3ef2
28 changed files with 456 additions and 312 deletions

View File

@ -34,8 +34,6 @@ add_executable(shooter
ShooterConsts.h ShooterConsts.h
# 3d engine: # 3d engine:
engine/Consts.h engine/Consts.h
engine/utils/Time.h
engine/utils/Time.cpp
engine/Point4D.h engine/Point4D.h
engine/Point4D.cpp engine/Point4D.cpp
engine/Vec3D.cpp engine/Vec3D.cpp
@ -52,6 +50,8 @@ add_executable(shooter
engine/Mesh.cpp engine/Mesh.cpp
engine/utils/Log.h engine/utils/Log.h
engine/utils/Log.cpp engine/utils/Log.cpp
engine/utils/Time.h
engine/utils/Time.cpp
engine/ResourceManager.h engine/ResourceManager.h
engine/ResourceManager.cpp engine/ResourceManager.cpp
engine/World.h engine/World.h
@ -75,6 +75,7 @@ add_executable(shooter
engine/animation/AScale.h engine/animation/AScale.h
engine/animation/ARotate.h engine/animation/ARotate.h
engine/animation/AWait.h engine/animation/AWait.h
engine/animation/AFunction.h
engine/physics/RigidBody.cpp engine/physics/RigidBody.cpp
engine/physics/RigidBody.h engine/physics/RigidBody.h
engine/physics/Simplex.h engine/physics/Simplex.h
@ -96,8 +97,7 @@ add_executable(shooter
engine/network/UDPConnection.h engine/network/UDPConnection.h
engine/network/UDPSocket.cpp engine/network/UDPSocket.cpp
engine/network/UDPSocket.h engine/network/UDPSocket.h
engine/animation/AFunction.h engine/SoundController.cpp engine/SoundController.h)
)
if(APPLE OR UNIX) if(APPLE OR UNIX)
include_directories(/usr/local/include) include_directories(/usr/local/include)

View File

@ -82,15 +82,15 @@ void Client::processCustomPacket(MsgType type, sf::Packet& packet) {
_player->addDeath(); _player->addDeath();
// respawn // respawn
_player->translateToPoint(Vec3D{50.0*(-1 + 2.0*(double)rand()/RAND_MAX),30.0*(double)rand()/RAND_MAX,50.0*(-1 + 2.0*(double)rand()/RAND_MAX)}); _player->translateToPoint(Vec3D{50.0*(-1 + 2.0*(double)rand()/RAND_MAX),30.0*(double)rand()/RAND_MAX,50.0*(-1 + 2.0*(double)rand()/RAND_MAX)});
_player->playDeath();
_player->initWeapons(); _player->initWeapons();
_player->setFullAbility(); _player->setFullAbility();
SoundController::playSound(SoundTag("death"), ShooterConsts::DEATH_SOUND);
} }
else else
_players[buffId[0]]->addDeath(); _players[buffId[0]]->addDeath();
if(buffId[1] == _socket.ownId()) { if(buffId[1] == _socket.ownId()) {
_player->addKill(); _player->addKill();
_player->playKill(); SoundController::playSound(SoundTag("kill"), ShooterConsts::KILL_SOUND);
} }
else else
_players[buffId[1]]->addKill(); _players[buffId[1]]->addKill();

View File

@ -14,11 +14,6 @@ Player::Player() {
setVisible(false); setVisible(false);
setColor({240, 168, 168}); setColor({240, 168, 168});
_changeWeaponSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::CHANGE_WEAPON_SOUND));
_fullHealthSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RESTORE_HEALTH_SOUND));
_fullAbilitySound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RESTORE_ABILITY_SOUND));
setCollisionCallBack([this](const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj) {collisionWithObject(tag, obj);}); setCollisionCallBack([this](const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj) {collisionWithObject(tag, obj);});
} }
@ -27,16 +22,6 @@ void Player::rotateWeaponsRelativePoint(const Vec3D& point4D, const Vec3D& v, do
weapon->rotateRelativePoint(point4D, v, val); weapon->rotateRelativePoint(point4D, v, val);
} }
void Player::playDeath() {
_deathSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::DEATH_SOUND));
_deathSound.play();
}
void Player::playKill() {
_killSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::KILL_SOUND));
_killSound.play();
}
void Player::collisionWithObject(const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj) { void Player::collisionWithObject(const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj) {
if(tag.str().find("Bonus_gun") != std::string::npos) if(tag.str().find("Bonus_gun") != std::string::npos)
addWeapon(std::make_shared<Gun>()); addWeapon(std::make_shared<Gun>());
@ -65,7 +50,7 @@ void Player::collisionWithObject(const ObjectNameTag& tag, std::shared_ptr<Rigid
} }
void Player::addWeapon(std::shared_ptr<Weapon> weapon) { void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
_changeWeaponSound.play(); SoundController::playSound(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
for(auto& w : _weapons) { for(auto& w : _weapons) {
if (w->name() == weapon->name()) { if (w->name() == weapon->name()) {
@ -106,7 +91,7 @@ void Player::nextWeapon() {
_selectedWeapon = (_selectedWeapon + 1) % _weapons.size(); _selectedWeapon = (_selectedWeapon + 1) % _weapons.size();
_addWeaponCallBack(_weapons[_selectedWeapon]); _addWeaponCallBack(_weapons[_selectedWeapon]);
Log::log("selectedWeapon " + std::to_string(_selectedWeapon)); Log::log("selectedWeapon " + std::to_string(_selectedWeapon));
_changeWeaponSound.play(); SoundController::playSound(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
} }
} }
@ -120,7 +105,7 @@ void Player::previousWeapon() {
_selectedWeapon = _weapons.size() - 1; _selectedWeapon = _weapons.size() - 1;
_addWeaponCallBack(_weapons[_selectedWeapon]); _addWeaponCallBack(_weapons[_selectedWeapon]);
Log::log("selectedWeapon " + std::to_string(_selectedWeapon)); Log::log("selectedWeapon " + std::to_string(_selectedWeapon));
_changeWeaponSound.play(); SoundController::playSound(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
} }
} }
@ -140,10 +125,10 @@ void Player::reload() {
void Player::setFullHealth() { void Player::setFullHealth() {
_health = ShooterConsts::HEALTH_MAX; _health = ShooterConsts::HEALTH_MAX;
_fullHealthSound.play(); SoundController::playSound(SoundTag("addHealth"), ShooterConsts::RESTORE_HEALTH_SOUND);
} }
void Player::setFullAbility() { void Player::setFullAbility() {
_ability = ShooterConsts::ABILITY_MAX; _ability = ShooterConsts::ABILITY_MAX;
_fullAbilitySound.play(); SoundController::playSound(SoundTag("addAbility"), ShooterConsts::RESTORE_ABILITY_SOUND);
} }

View File

@ -27,13 +27,6 @@ private:
int _kills = 0; int _kills = 0;
int _deaths = 0; int _deaths = 0;
// sounds
sf::Sound _killSound;
sf::Sound _deathSound;
sf::Sound _changeWeaponSound;
sf::Sound _fullHealthSound;
sf::Sound _fullAbilitySound;
std::vector<std::shared_ptr<Weapon>> _weapons; std::vector<std::shared_ptr<Weapon>> _weapons;
size_t _selectedWeapon = 0; size_t _selectedWeapon = 0;
@ -48,12 +41,8 @@ private:
public: public:
Player(); Player();
void setHealth(double h) { void setHealth(double h) { _health = h; }
_health = h; void setAbility(double a) { _ability = a; }
}
void setAbility(double a) {
_ability = a;
}
[[nodiscard]] double health() const { return _health; } [[nodiscard]] double health() const { return _health; }
[[nodiscard]] double ability() const { return _ability; } [[nodiscard]] double ability() const { return _ability; }
@ -73,15 +62,12 @@ public:
void rotateWeaponsRelativePoint(const Vec3D& point, const Vec3D& v, double val); void rotateWeaponsRelativePoint(const Vec3D& point, const Vec3D& v, double val);
[[nodiscard]] int kills() const {return _kills;} [[nodiscard]] int kills() const { return _kills; }
[[nodiscard]] int deaths() const {return _deaths;} [[nodiscard]] int deaths() const { return _deaths; }
void addKill() { _kills++; } void addKill() { _kills++; }
void addDeath() { _deaths++; } void addDeath() { _deaths++; }
void playDeath();
void playKill();
void setDamagePlayerCallBack(std::function<void(sf::Uint16 targetId, double)> hit) { void setDamagePlayerCallBack(std::function<void(sf::Uint16 targetId, double)> hit) {
_damagePlayerCallBack = std::move(hit); _damagePlayerCallBack = std::move(hit);
} }

View File

@ -13,10 +13,7 @@
PlayerController::PlayerController(std::shared_ptr<Player> player, PlayerController::PlayerController(std::shared_ptr<Player> player,
std::shared_ptr<Keyboard> keyboard, std::shared_ptr<Keyboard> keyboard,
std::shared_ptr<Mouse> mouse) : _player(player), _keyboard(keyboard), _mouse(mouse) { std::shared_ptr<Mouse> mouse) : _player(player), _keyboard(keyboard), _mouse(mouse) {}
_slowMoSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::SLOW_MO_SOUND));
_unSlowMoSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::UN_SLOW_MO_SOUND));
}
void PlayerController::update() { void PlayerController::update() {
// friction // friction
@ -31,8 +28,8 @@ void PlayerController::update() {
_isInSlowMo = false; _isInSlowMo = false;
_player->setVelocity(_player->velocity() * ShooterConsts::SLOW_MO_COEFFICIENT); _player->setVelocity(_player->velocity() * ShooterConsts::SLOW_MO_COEFFICIENT);
_player->setAcceleration(_player->acceleration() * ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT); _player->setAcceleration(_player->acceleration() * ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT);
_slowMoSound.stop(); SoundController::stopSound(SoundTag("slowMo"));
_unSlowMoSound.play(); SoundController::playSound(SoundTag("unSlowMo"), ShooterConsts::UN_SLOW_MO_SOUND);
} }
} }
@ -100,14 +97,14 @@ void PlayerController::update() {
_isInSlowMo = true; _isInSlowMo = true;
_player->setVelocity(_player->velocity() / ShooterConsts::SLOW_MO_COEFFICIENT); _player->setVelocity(_player->velocity() / ShooterConsts::SLOW_MO_COEFFICIENT);
_player->setAcceleration(Vec3D(0, -ShooterConsts::GRAVITY / (ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT), 0)); _player->setAcceleration(Vec3D(0, -ShooterConsts::GRAVITY / (ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT), 0));
_unSlowMoSound.stop(); SoundController::stopSound(SoundTag("unSlowMo"));
_slowMoSound.play(); SoundController::playSound(SoundTag("slowMo"), ShooterConsts::SLOW_MO_SOUND);
} else if (_isInSlowMo && !Keyboard::isKeyPressed(sf::Keyboard::LShift)) { } else if (_isInSlowMo && !Keyboard::isKeyPressed(sf::Keyboard::LShift)) {
_isInSlowMo = false; _isInSlowMo = false;
_player->setVelocity(_player->velocity() * ShooterConsts::SLOW_MO_COEFFICIENT); _player->setVelocity(_player->velocity() * ShooterConsts::SLOW_MO_COEFFICIENT);
_player->setAcceleration(Vec3D(0, -ShooterConsts::GRAVITY, 0)); _player->setAcceleration(Vec3D(0, -ShooterConsts::GRAVITY, 0));
_slowMoSound.stop(); SoundController::stopSound(SoundTag("slowMo"));
_unSlowMoSound.play(); SoundController::playSound(SoundTag("unSlowMo"), ShooterConsts::UN_SLOW_MO_SOUND);
} }
if (Keyboard::isKeyPressed(sf::Keyboard::Space) && _player->inCollision()) { if (Keyboard::isKeyPressed(sf::Keyboard::Space) && _player->inCollision()) {
@ -160,9 +157,8 @@ void PlayerController::update() {
_player->reload(); _player->reload();
} }
if ((_inRunning || _player->velocity().sqrAbs() > 3) && _player->inCollision() && _walkSound.getStatus() != sf::Sound::Status::Playing) { if ((_inRunning || _player->velocity().sqrAbs() > 3) && _player->inCollision() && SoundController::getStatus(SoundTag("walk")) != sf::Sound::Status::Playing) {
int soundNum = (int)((double) rand() / RAND_MAX * 5) + 1; int soundNum = (int)((double) rand() / RAND_MAX * 5) + 1;
_walkSound.setBuffer(*ResourceManager::loadSoundBuffer("sound/stonestep" + std::to_string(soundNum) + ".ogg")); SoundController::playSound(SoundTag("walk"), "sound/stonestep" + std::to_string(soundNum) + ".ogg");
_walkSound.play();
} }
} }

View File

@ -19,10 +19,6 @@ private:
bool _isSliding = false; bool _isSliding = false;
bool _isInSlowMo = false; bool _isInSlowMo = false;
sf::Sound _slowMoSound;
sf::Sound _unSlowMoSound;
sf::Sound _walkSound;
public: public:
PlayerController(std::shared_ptr<Player> player, std::shared_ptr<Keyboard> keyboard, std::shared_ptr<Mouse> mouse); PlayerController(std::shared_ptr<Player> player, std::shared_ptr<Keyboard> keyboard, std::shared_ptr<Mouse> mouse);
void update(); void update();

View File

@ -9,6 +9,7 @@
#include "engine/animation/ARotate.h" #include "engine/animation/ARotate.h"
#include "engine/animation/Timeline.h" #include "engine/animation/Timeline.h"
#include "ShooterConsts.h" #include "ShooterConsts.h"
#include "engine/SoundController.h"
using namespace std; using namespace std;
@ -96,10 +97,10 @@ void Shooter::start() {
mainMenu.title("Main menu"); mainMenu.title("Main menu");
mainMenu.setBackgroundTexture(ShooterConsts::MAIN_MENU_BACK, 1.1, 1.1, screen->width(), screen->height()); mainMenu.setBackgroundTexture(ShooterConsts::MAIN_MENU_BACK, 1.1, 1.1, screen->width(), screen->height());
mainMenu.addButton(screen->width()/2, 200, 200, 20, [this] () { this->play(); }, "Play", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255}, ShooterConsts::CLICK_SOUND); mainMenu.addButton(screen->width()/2, 200, 200, 20, [this] () { this->play(); SoundController::playSound(SoundTag("click"), ShooterConsts::CLICK_SOUND);}, "Play", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255});
mainMenu.addButton(screen->width()/2, 350, 200, 20, [this] () { this->player->translateToPoint(Vec3D{0, 0, 0}); this->player->setVelocity({}); this->play(); }, "Respawn", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255}, ShooterConsts::CLICK_SOUND); mainMenu.addButton(screen->width()/2, 350, 200, 20, [this] () { this->player->translateToPoint(Vec3D{0, 0, 0}); this->player->setVelocity({}); this->play(); SoundController::playSound(SoundTag("click"), ShooterConsts::CLICK_SOUND);}, "Respawn", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255});
mainMenu.addButton(screen->width()/2, 500, 200, 20, [this] () { client->disconnect(); server->stop(); this->exit();}, "Exit", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255}, ShooterConsts::CLICK_SOUND); mainMenu.addButton(screen->width()/2, 500, 200, 20, [this] () { client->disconnect(); server->stop(); this->exit();}, "Exit", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255});
// connecting to the server // connecting to the server
InitNetwork(); InitNetwork();
@ -144,10 +145,8 @@ void Shooter::update() {
setUpdateWorld(inGame); setUpdateWorld(inGame);
// background sounds and music control // background sounds and music control
if(backgroundNoise.getStatus() != sf::Sound::Status::Playing) { if(SoundController::getStatus(SoundTag("background")) != sf::Sound::Status::Playing)
backgroundNoise.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::BACK_NOISE)); SoundController::playSound(SoundTag("background"), ShooterConsts::BACK_NOISE);
backgroundNoise.play();
}
} }
void Shooter::gui() { void Shooter::gui() {

View File

@ -24,6 +24,7 @@ namespace Consts {
const std::string THIN_FONT = "engine/fonts/Roboto-Thin.ttf"; const std::string THIN_FONT = "engine/fonts/Roboto-Thin.ttf";
const std::string MEDIUM_FONT = "engine/fonts/Roboto-Medium.ttf"; const std::string MEDIUM_FONT = "engine/fonts/Roboto-Medium.ttf";
const double LARGEST_TIME_STEP = 1.0/15.0;
const double TAP_DELAY = 0.2; const double TAP_DELAY = 0.2;
const unsigned NETWORK_VERSION = 1U; const unsigned NETWORK_VERSION = 1U;

View File

@ -7,8 +7,14 @@
#include <iostream> #include <iostream>
#include "ResourceManager.h" #include "ResourceManager.h"
#include "animation/Timeline.h" #include "animation/Timeline.h"
#include "SoundController.h"
Engine::Engine() { Engine::Engine() {
Time::init();
Timeline::init();
ResourceManager::init();
SoundController::init();
screen = std::make_shared<Screen>(); screen = std::make_shared<Screen>();
keyboard = std::make_shared<Keyboard>(); keyboard = std::make_shared<Keyboard>();
mouse = std::make_shared<Mouse>(); mouse = std::make_shared<Mouse>();
@ -64,14 +70,17 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name,
screen->display(); screen->display();
} }
exit();
} }
void Engine::exit() { void Engine::exit() {
if(screen->isOpen()) { if(screen->isOpen()) {
screen->close(); screen->close();
} }
ResourceManager::unloadAllResources(); SoundController::free();
ResourceManager::free();
Timeline::free();
Time::free();
Log::log("Engine::exit(): exit engine (" + std::to_string(screen->width()) + "x" + std::to_string(screen->height()) + ") with title '" + Log::log("Engine::exit(): exit engine (" + std::to_string(screen->width()) + "x" + std::to_string(screen->height()) + ") with title '" +
screen->title() + "'."); screen->title() + "'.");
} }

View File

@ -6,93 +6,100 @@
#include <map> #include <map>
#include <memory> #include <memory>
namespace ResourceManager ResourceManager* ResourceManager::_instance = nullptr;
{
namespace
{
std::map<std::string, std::shared_ptr<sf::Texture>> _textures;
std::map<std::string, std::shared_ptr<sf::Font>> _fonts;
std::map<std::string, std::shared_ptr<sf::SoundBuffer>> _soundBuffers;
}
void unloadTextures() void ResourceManager::init() {
{ _instance = new ResourceManager();
for (auto & _texture : _textures)
_texture.second.reset();
_textures.clear();
}
void unloadSoundBuffers()
{
for (auto & _soundBuffer : _soundBuffers)
_soundBuffer.second.reset();
_soundBuffers.clear();
}
void unloadFonts() {
for (auto & _font : _fonts)
_font.second.reset();
_fonts.clear();
}
void unloadAllResources()
{
unloadTextures();
unloadSoundBuffers();
unloadFonts();
}
std::shared_ptr<sf::Texture> loadTexture(const std::string& filename)
{
// If texture is already loaded - return pointer to it
auto it = _textures.find(filename);
if (it != _textures.end())
return it->second;
// Otherwise - try to load it. If failure - return zero
std::shared_ptr<sf::Texture> texture(new sf::Texture);
if (!texture->loadFromFile(filename))
return nullptr;
// If success - remember and return texture pointer
texture->setRepeated(true);
_textures.emplace(filename, texture);
return texture;
}
std::shared_ptr<sf::SoundBuffer> loadSoundBuffer(const std::string& filename)
{
// If sound buffer is already loaded - return pointer to it
auto it = _soundBuffers.find(filename);
if (it != _soundBuffers.end())
return it->second;
// Otherwise - try to load it. If failure - return zero
std::shared_ptr<sf::SoundBuffer> soundBuffer(new sf::SoundBuffer);
if (!soundBuffer->loadFromFile(filename))
return nullptr;
// If success - remember and return texture pointer
_soundBuffers.emplace(filename, soundBuffer);
return soundBuffer;
}
std::shared_ptr<sf::Font> loadFont(const std::string& filename) {
// If font is already loaded - return pointer to it
auto it = _fonts.find(filename);
if (it != _fonts.end())
return it->second;
// Otherwise - try to load it. If failure - return zero
std::shared_ptr<sf::Font> font(new sf::Font);
if (!font->loadFromFile(filename))
return nullptr;
// If success - remember and return texture pointer
_fonts.emplace(filename, font);
return font;
}
} }
void ResourceManager::unloadTextures() {
for (auto & _texture : _instance->_textures)
_texture.second.reset();
_instance->_textures.clear();
}
void ResourceManager::unloadSoundBuffers() {
for (auto & _soundBuffer : _instance->_soundBuffers)
_soundBuffer.second.reset();
_instance->_soundBuffers.clear();
}
void ResourceManager::unloadFonts() {
for (auto & _font : _instance->_fonts)
_font.second.reset();
_instance->_fonts.clear();
}
void ResourceManager::unloadAllResources() {
unloadTextures();
unloadSoundBuffers();
unloadFonts();
}
std::shared_ptr<sf::Texture> ResourceManager::loadTexture(const std::string& filename) {
if(!_instance)
return nullptr;
// If texture is already loaded - return pointer to it
auto it = _instance->_textures.find(filename);
if (it != _instance->_textures.end())
return it->second;
// Otherwise - try to load it. If failure - return zero
std::shared_ptr<sf::Texture> texture(new sf::Texture);
if (!texture->loadFromFile(filename))
return nullptr;
// If success - remember and return texture pointer
texture->setRepeated(true);
_instance->_textures.emplace(filename, texture);
return texture;
}
std::shared_ptr<sf::SoundBuffer> ResourceManager::loadSoundBuffer(const std::string& filename) {
if(!_instance)
return nullptr;
// If sound buffer is already loaded - return pointer to it
auto it = _instance->_soundBuffers.find(filename);
if (it != _instance->_soundBuffers.end())
return it->second;
// Otherwise - try to load it. If failure - return zero
std::shared_ptr<sf::SoundBuffer> soundBuffer(new sf::SoundBuffer);
if (!soundBuffer->loadFromFile(filename))
return nullptr;
// If success - remember and return texture pointer
_instance->_soundBuffers.emplace(filename, soundBuffer);
return soundBuffer;
}
std::shared_ptr<sf::Font> ResourceManager::loadFont(const std::string& filename) {
if(!_instance)
return nullptr;
// If font is already loaded - return pointer to it
auto it = _instance->_fonts.find(filename);
if (it != _instance->_fonts.end())
return it->second;
// Otherwise - try to load it. If failure - return zero
std::shared_ptr<sf::Font> font(new sf::Font);
if (!font->loadFromFile(filename))
return nullptr;
// If success - remember and return texture pointer
_instance->_fonts.emplace(filename, font);
return font;
}
void ResourceManager::free() {
unloadAllResources();
delete _instance;
_instance = nullptr;
}

View File

@ -9,23 +9,36 @@
#include <SFML/Audio.hpp> #include <SFML/Audio.hpp>
#include <memory> #include <memory>
namespace ResourceManager class ResourceManager final {
{ private:
// Unloads all currently loaded textures. std::map<std::string, std::shared_ptr<sf::Texture>> _textures;
void unloadTextures(); std::map<std::string, std::shared_ptr<sf::Font>> _fonts;
void unloadSoundBuffers(); std::map<std::string, std::shared_ptr<sf::SoundBuffer>> _soundBuffers;
void unloadFonts();
void unloadShaders();
void unloadAllResources(); static ResourceManager* _instance;
ResourceManager() = default;
public:
ResourceManager(const ResourceManager&) = delete;
ResourceManager& operator=(ResourceManager&) = delete;
// Unloads all currently loaded textures.
static void unloadTextures();
static void unloadSoundBuffers();
static void unloadFonts();
static void unloadShaders();
static void unloadAllResources();
static void init();
static void free();
// Try to load texture from file. // Try to load texture from file.
// If success returns pointer to texture. // If success returns pointer to texture.
// Otherwise returns nullptr. // Otherwise returns nullptr.
std::shared_ptr<sf::Texture> loadTexture(const std::string& filename); static std::shared_ptr<sf::Texture> loadTexture(const std::string& filename);
std::shared_ptr<sf::Font> loadFont(const std::string& filename); static std::shared_ptr<sf::Font> loadFont(const std::string& filename);
std::shared_ptr<sf::SoundBuffer> loadSoundBuffer(const std::string& filename); static std::shared_ptr<sf::SoundBuffer> loadSoundBuffer(const std::string& filename);
}; };
#endif //PSEUDO3DENGINE_RESOURCEMANAGER_H #endif //PSEUDO3DENGINE_RESOURCEMANAGER_H

View File

@ -0,0 +1,60 @@
//
// Created by Иван Ильин on 17.10.2021.
//
#include "SoundController.h"
#include "ResourceManager.h"
SoundController* SoundController::_instance = nullptr;
void SoundController::init() {
_instance = new SoundController();
}
void SoundController::playSound(const SoundTag& soundTag, const std::string& filename) {
if(!_instance)
return;
stopSound(soundTag);
_instance->_sounds.emplace(soundTag, sf::Sound(*ResourceManager::loadSoundBuffer(filename)));
_instance->_sounds[soundTag].play();
}
void SoundController::pauseSound(const SoundTag& soundTag) {
if(!_instance)
return;
if(_instance->_sounds.count(soundTag) > 0) {
_instance->_sounds[soundTag].pause();
}
}
void SoundController::stopSound(const SoundTag& soundTag) {
if(!_instance)
return;
if(_instance->_sounds.count(soundTag) > 0) {
_instance->_sounds[soundTag].stop();
}
_instance->_sounds.erase(soundTag);
}
sf::Sound::Status SoundController::getStatus(const SoundTag& soundTag) {
if(_instance == nullptr)
return sf::Sound::Status::Stopped;
if(_instance->_sounds.count(soundTag) > 0)
return _instance->_sounds[soundTag].getStatus();
else
return sf::Sound::Status::Stopped;
}
void SoundController::free() {
for(auto& [soundTag, sound] : _instance->_sounds) {
sound.stop();
}
_instance->_sounds.clear();
delete _instance;
_instance = nullptr;
}

45
engine/SoundController.h Normal file
View File

@ -0,0 +1,45 @@
//
// Created by Иван Ильин on 17.10.2021.
//
#ifndef SHOOTER_SOUNDCONTROLLER_H
#define SHOOTER_SOUNDCONTROLLER_H
#include <string>
#include <map>
#include <SFML/Audio.hpp>
class SoundTag final {
private:
const std::string _name;
public:
explicit SoundTag(std::string name = "") : _name(std::move(name)) {}
[[nodiscard]] std::string str() const { return _name; }
bool operator==(const SoundTag& tag) const { return _name == tag._name; }
bool operator!=(const SoundTag& tag) const { return _name != tag._name; }
bool operator<(const SoundTag& tag) const { return _name < tag._name; }
};
class SoundController final {
private:
std::map<SoundTag, sf::Sound> _sounds;
static SoundController* _instance;
SoundController() = default;
public:
SoundController(const SoundController&) = delete;
SoundController& operator=(SoundController&) = delete;
static void playSound(const SoundTag& soundTag, const std::string& filename);
static void pauseSound(const SoundTag& soundTag);
static void stopSound(const SoundTag& soundTag);
static sf::Sound::Status getStatus(const SoundTag& soundTag);
static void init();
static void free();
};
#endif //SHOOTER_SOUNDCONTROLLER_H

View File

@ -6,49 +6,77 @@
#include "Animation.h" #include "Animation.h"
#include "Timeline.h" #include "Timeline.h"
namespace Timeline { Timeline* Timeline::_instance = nullptr;
namespace {
std::map<AnimationListTag, std::list<Animation*>> _animations; void Timeline::init() {
_instance = new Timeline();
}
void Timeline::animate(const AnimationListTag& listName, Animation* anim) {
if(!_instance)
return;
_instance->_animations[listName].emplace_back(anim);
}
void Timeline::deleteAllAnimations() {
if(!_instance)
return;
for (auto& [listName, animationList] : _instance->_animations) {
auto it = animationList.begin();
while(it != animationList.end())
delete *(it++);
animationList.clear();
} }
_instance->_animations.clear();
}
void animate(const AnimationListTag& listName, Animation* anim) { void Timeline::deleteAnimationList(const AnimationListTag& listName) {
_animations[listName].emplace_back(anim); if(!_instance)
} return;
void deleteAllAnimations() { _instance->_animations[listName].clear();
_animations.clear(); _instance->_animations.erase(listName);
} }
void deleteAnimationList(const AnimationListTag& listName) { [[nodiscard]] bool Timeline::isInAnimList(const AnimationListTag& listName) {
_animations[listName].clear(); if(!_instance)
_animations.erase(listName); return false;
}
[[nodiscard]] bool isInAnimList(const AnimationListTag& listName) { return !_instance->_animations[listName].empty();
return !_animations[listName].empty(); }
}
void update() { void Timeline::update() {
for (auto& [listName, animationList] : _animations) { if(!_instance)
return;
if (animationList.empty()) for (auto& [listName, animationList] : _instance->_animations) {
continue;
auto it = animationList.begin();
// If it the front animation is 'a_wait()' we should wait until waiting time is over
if (it.operator*()->waitFor()) { if (animationList.empty())
if (!it.operator*()->update()) continue;
animationList.erase(it); auto it = animationList.begin();
continue; // If it the front animation is 'a_wait()' we should wait until waiting time is over
}
// Otherwise we iterate over all animation until we meet animations.end() or wait animation if (it.operator*()->waitFor()) {
while (!animationList.empty() && (it != animationList.end()) && (!it.operator*()->waitFor())) { if (!it.operator*()->update())
if (!it.operator*()->update()) animationList.erase(it);
animationList.erase(it++); continue;
else }
it++;
} // Otherwise we iterate over all animation until we meet animations.end() or wait animation
while (!animationList.empty() && (it != animationList.end()) && (!it.operator*()->waitFor())) {
if (!it.operator*()->update())
animationList.erase(it++);
else
it++;
} }
} }
} }
void Timeline::free() {
Timeline::deleteAllAnimations();
delete _instance;
_instance = nullptr;
}

View File

@ -19,14 +19,27 @@ public:
bool operator<(const AnimationListTag& tag) const { return _name < tag._name; } bool operator<(const AnimationListTag& tag) const { return _name < tag._name; }
}; };
namespace Timeline { class Timeline {
void update(); private:
void animate(const AnimationListTag& listName, Animation* anim); std::map<AnimationListTag, std::list<Animation*>> _animations;
void deleteAllAnimations(); static Timeline* _instance;
void deleteAnimationList(const AnimationListTag& listName);
[[nodiscard]] bool isInAnimList(const AnimationListTag& listName); Timeline() = default;
} public:
Timeline(const Timeline&) = delete;
Timeline& operator=(Timeline&) = delete;
static void update();
static void animate(const AnimationListTag& listName, Animation* anim);
static void deleteAllAnimations();
static void deleteAnimationList(const AnimationListTag& listName);
[[nodiscard]] static bool isInAnimList(const AnimationListTag& listName);
static void init();
static void free();
};
#endif //SHOOTER_TIMELINE_H #endif //SHOOTER_TIMELINE_H

View File

@ -32,7 +32,7 @@ void Button::press()
_button.setTextureRect(sf::IntRect(_pressedState.tx, _pressedState.ty, _w, _h)); _button.setTextureRect(sf::IntRect(_pressedState.tx, _pressedState.ty, _w, _h));
if(_checkBox) if(_checkBox)
_pressed = true; _pressed = true;
_clickSound.play(); //_clickSound.play();
_click(); _click();
} }
else else
@ -55,14 +55,14 @@ void Button::init() {
_text.setFillColor(_textColor); _text.setFillColor(_textColor);
_text.setPosition((float)(_x - _text.getLocalBounds().width / 2), (float)(_y - _h * _sy / 2 + _text.getLocalBounds().height / 4)); _text.setPosition((float)(_x - _text.getLocalBounds().width / 2), (float)(_y - _h * _sy / 2 + _text.getLocalBounds().height / 4));
_clickSound.setBuffer(*ResourceManager::loadSoundBuffer(_clickSoundName)); //_clickSound.setBuffer(*ResourceManager::loadSoundBuffer(_clickSoundName));
_clickSound.setVolume(15); //_clickSound.setVolume(15);
} }
Button::Button(int x, int y, int width, int height, std::function<void()> click, std::string text, double sx, Button::Button(int x, int y, int width, int height, std::function<void()> click, std::string text, double sx,
double sy, std::string texture, tPos usualState, tPos selectedState, tPos pressedState, double sy, std::string texture, tPos usualState, tPos selectedState, tPos pressedState,
std::string font, sf::Color textColor, std::string clickSound) : _x(x), _y(y), _w(width), _h(height), _click(std::move(click)), std::string font, sf::Color textColor) : _x(x), _y(y), _w(width), _h(height), _click(std::move(click)),
_textString(std::move(text)), _sx(sx), _sy(sy), _texture(std::move(texture)), _usualState(usualState), _selectedState(selectedState), _pressedState(pressedState), _textString(std::move(text)), _sx(sx), _sy(sy), _texture(std::move(texture)), _usualState(usualState), _selectedState(selectedState), _pressedState(pressedState),
_font(std::move(font)), _textColor(textColor), _clickSoundName(std::move(clickSound)){ _font(std::move(font)), _textColor(textColor) {
} }

View File

@ -9,9 +9,9 @@
#include <SFML/Audio.hpp> #include <SFML/Audio.hpp>
#include <functional> #include <functional>
struct tPos { struct tPos final {
int tx; const int tx;
int ty; const int ty;
}; };
class Button final { class Button final {
@ -37,11 +37,8 @@ private:
std::string _font; std::string _font;
sf::Color _textColor; sf::Color _textColor;
std::string _clickSoundName;
sf::Sprite _button; sf::Sprite _button;
sf::Text _text; sf::Text _text;
sf::Sound _clickSound;
bool _selected = false; bool _selected = false;
bool _pressed = false; bool _pressed = false;
@ -49,7 +46,7 @@ private:
public: public:
Button() = default; Button() = default;
Button(int x, int y, int width, int height, std::function<void()> click, std::string text, double sx, double sy, std::string texture, tPos usualState, tPos selectedState, tPos pressedState, std::string font, sf::Color textColor, std::string clickSound); Button(int x, int y, int width, int height, std::function<void()> click, std::string text, double sx, double sy, std::string texture, tPos usualState, tPos selectedState, tPos pressedState, std::string font, sf::Color textColor);
void select(); void select();
void unSelect(); void unSelect();

View File

@ -9,8 +9,8 @@
void Window::addButton(int x, int y, int w, int h, std::function<void()> click, const std::string &text, double sx, double sy, void Window::addButton(int x, int y, int w, int h, std::function<void()> click, const std::string &text, double sx, double sy,
const std::string &texture, tPos usualState, tPos selectedState, tPos pressedState, const std::string &texture, tPos usualState, tPos selectedState, tPos pressedState,
const std::string& font, sf::Color textColor, const std::string& clickSound) { const std::string& font, sf::Color textColor) {
_buttons.push_back(Button{x, y, w, h, std::move(click), text, sx, sy, texture, usualState, selectedState, pressedState, font, textColor, clickSound}); _buttons.push_back(Button{x, y, w, h, std::move(click), text, sx, sy, texture, usualState, selectedState, pressedState, font, textColor});
_buttons.back().init(); _buttons.back().init();
} }

View File

@ -31,7 +31,7 @@ public:
std::function<void()> click, std::function<void()> click,
const std::string& text = "_button", double sx = 1, double sy = 1, const std::string& text = "_button", double sx = 1, double sy = 1,
const std::string& texture = "", tPos usualState = {}, tPos selectedState = {}, tPos pressedState = {}, const std::string& texture = "", tPos usualState = {}, tPos selectedState = {}, tPos pressedState = {},
const std::string& font = Consts::MEDIUM_FONT, sf::Color textColor = {255, 255, 255}, const std::string& clickSound = ""); const std::string& font = Consts::MEDIUM_FONT, sf::Color textColor = {255, 255, 255});
[[nodiscard]] std::string title() const { return _name; } [[nodiscard]] std::string title() const { return _name; }
void title(const std::string& title) { _name = title; } void title(const std::string& title) { _name = title; }

View File

@ -3,76 +3,65 @@
// //
#include "Time.h" #include "Time.h"
#include <chrono> #include "../Consts.h"
#define BIG_STEP (1.0/15.0)
using namespace std::chrono; using namespace std::chrono;
namespace Time Time* Time::_instance = nullptr;
{
namespace
{
// High precision time
high_resolution_clock::time_point _start = high_resolution_clock::now();
high_resolution_clock::time_point _last = _start;
// FPS counter void Time::init() {
high_resolution_clock::time_point _fpsStart; _instance = new Time();
milliseconds _fpsCountTime = milliseconds(1000); }
int _fpsCounter = 0;
double _lastFps = 0;
// Compatibility double Time::time() {
double _time; if(!_instance)
double _deltaTime; return 0;
double _realDeltaTime;
}
double time() return _instance->_time;
{ }
return _time;
}
double deltaTime() double Time::deltaTime() {
{ if(!_instance)
return _deltaTime; return 0;
}
double realDeltaTime() return _instance->_deltaTime;
{ }
return _realDeltaTime;
}
void update() void Time::update() {
{ if(!_instance)
high_resolution_clock::time_point t = high_resolution_clock::now(); return;
high_resolution_clock::time_point t = high_resolution_clock::now();
_deltaTime = duration<double>(t - _last).count(); _instance->_deltaTime = duration<double>(t - _instance->_last).count();
_time = duration<double>(t - _start).count(); _instance->_time = duration<double>(t - _instance->_start).count();
// in case when fps < 10 it is useful to decrease _deltaTime (to avoid collision problems) // in case when fps < 10 it is useful to decrease _deltaTime (to avoid collision problems)
if(_deltaTime > BIG_STEP) if(_instance->_deltaTime > Consts::LARGEST_TIME_STEP)
_deltaTime = BIG_STEP; _instance->_deltaTime = Consts::LARGEST_TIME_STEP;
_realDeltaTime = duration<double>(t - _last).count(); _instance->_last = t;
_last = t;
if(_deltaTime > 10000) if(_instance->_deltaTime > 10000)
return; return;
_fpsCounter++; _instance->_fpsCounter++;
if (t - _fpsStart > _fpsCountTime) if (t - _instance->_fpsStart > _instance->_fpsCountTime) {
{ _instance->_lastFps = _instance->_fpsCounter / duration<double>(t - _instance->_fpsStart).count();
_lastFps = _fpsCounter / duration<double>(t - _fpsStart).count(); _instance->_fpsCounter = 0;
_fpsCounter = 0; _instance->_fpsStart = t;
_fpsStart = t;
}
}
int fps()
{
// Cast is faster than floor and has the same behavior for positive numbers
return static_cast<int>(_lastFps);
} }
} }
int Time::fps() {
if(!_instance)
return 0;
// Cast is faster than floor and has the same behavior for positive numbers
return static_cast<int>(_instance->_lastFps);
}
void Time::free() {
Time* t = _instance;
delete _instance;
_instance = nullptr;
}

View File

@ -5,14 +5,39 @@
#ifndef ENGINE_TIME_H #ifndef ENGINE_TIME_H
#define ENGINE_TIME_H #define ENGINE_TIME_H
namespace Time #include <chrono>
{
int fps();
double time();
double deltaTime();
double realDeltaTime();
void update();
}
class Time final {
private:
// High precision time
std::chrono::high_resolution_clock::time_point _start = std::chrono::high_resolution_clock::now();
std::chrono::high_resolution_clock::time_point _last = _start;
// FPS counter
std::chrono::high_resolution_clock::time_point _fpsStart{};
std::chrono::milliseconds _fpsCountTime = std::chrono::milliseconds(1000);
int _fpsCounter = 0;
double _lastFps = 0;
// Compatibility
double _time = 0;
double _deltaTime = 0;
static Time* _instance;
Time() = default;
public:
Time(const Time&) = delete;
Time& operator=(Time&) = delete;
static int fps();
static double time();
static double deltaTime();
static void update();
static void init();
static void free();
};
#endif //INC_3DZAVR_TIME_H #endif //INC_3DZAVR_TIME_H

View File

@ -9,8 +9,8 @@
using namespace std; using namespace std;
Ak47::Ak47(int ammo, const std::string& weaponName) : Weapon(weaponName, ShooterConsts::AK47_OBJ, "obj/ak47_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.8, 1.3, 0.3}, Vec3D{0, Consts::PI, 0}) { Ak47::Ak47(int ammo, const std::string& weaponName) : Weapon(weaponName, ShooterConsts::AK47_OBJ, "obj/ak47_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.8, 1.3, 0.3}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::AK47_FIRE_SOUND)); fireSound = ShooterConsts::AK47_FIRE_SOUND;
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::AK47_RELOAD_SOUND)); reloadSound = ShooterConsts::AK47_RELOAD_SOUND;
_stockAmmo = ammo - _clipCapacity; _stockAmmo = ammo - _clipCapacity;

View File

@ -11,8 +11,8 @@
class Gold_Ak47 final : public Weapon { class Gold_Ak47 final : public Weapon {
public: public:
explicit Gold_Ak47(int ammo = 200, const std::string& weaponName = "gold_ak47") : Weapon(weaponName, ShooterConsts::GOLD_AK47_OBJ, "obj/gold_ak47_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.8, 1.3, 0.3}, Vec3D{0, Consts::PI, 0}) { explicit Gold_Ak47(int ammo = 200, const std::string& weaponName = "gold_ak47") : Weapon(weaponName, ShooterConsts::GOLD_AK47_OBJ, "obj/gold_ak47_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.8, 1.3, 0.3}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::GOLD_AK47_FIRE_SOUND)); fireSound = ShooterConsts::GOLD_AK47_FIRE_SOUND;
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::GOLD_AK47_RELOAD_SOUND)); reloadSound = ShooterConsts::GOLD_AK47_RELOAD_SOUND;
_initialPack = 200; _initialPack = 200;
_spreading = 1.0; _spreading = 1.0;

View File

@ -9,8 +9,8 @@
using namespace std; using namespace std;
Gun::Gun(int ammo, const std::string& weaponName) : Weapon(weaponName, ShooterConsts::GUN_OBJ, "obj/gun_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.8, 1.3, 0.3}, Vec3D{0, Consts::PI, 0}) { Gun::Gun(int ammo, const std::string& weaponName) : Weapon(weaponName, ShooterConsts::GUN_OBJ, "obj/gun_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.8, 1.3, 0.3}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::GUN_FIRE_SOUND)); fireSound = ShooterConsts::GUN_FIRE_SOUND;
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::GUN_RELOAD_SOUND)); reloadSound = ShooterConsts::GUN_RELOAD_SOUND;
_initialPack = 30; _initialPack = 30;
_clipCapacity = 6; // how much ammo can be stored in one clip _clipCapacity = 6; // how much ammo can be stored in one clip

View File

@ -7,8 +7,8 @@
#include "../ShooterConsts.h" #include "../ShooterConsts.h"
Rifle::Rifle(int ammo, const std::string &weaponName) : Weapon(weaponName, ShooterConsts::RIFLE_OBJ, "obj/rifle_mat.txt", Vec3D{3, 3, 3}, Vec3D{-1.2, 1, 0.3}, Vec3D{0, Consts::PI, 0}) { Rifle::Rifle(int ammo, const std::string &weaponName) : Weapon(weaponName, ShooterConsts::RIFLE_OBJ, "obj/rifle_mat.txt", Vec3D{3, 3, 3}, Vec3D{-1.2, 1, 0.3}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RIFLE_FIRE_SOUND)); fireSound = ShooterConsts::RIFLE_FIRE_SOUND;
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RIFLE_RELOAD_SOUND)); reloadSound = ShooterConsts::RIFLE_RELOAD_SOUND;
_initialPack = 5; _initialPack = 5;
_clipCapacity = 1; // how much ammo can be stored in one clip _clipCapacity = 1; // how much ammo can be stored in one clip

View File

@ -10,8 +10,8 @@
using namespace std; using namespace std;
Shotgun::Shotgun(int ammo, const std::string& weaponName) : Weapon(weaponName, ShooterConsts::SHOTGUN_OBJ, "obj/shotgun_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.95, 1.3, -0.6}, Vec3D{0, Consts::PI, 0}) { Shotgun::Shotgun(int ammo, const std::string& weaponName) : Weapon(weaponName, ShooterConsts::SHOTGUN_OBJ, "obj/shotgun_mat.txt", Vec3D{3, 3, 3}, Vec3D{-0.95, 1.3, -0.6}, Vec3D{0, Consts::PI, 0}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::SHOTGUN_FIRE_SOUND)); fireSound = ShooterConsts::SHOTGUN_FIRE_SOUND;
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::SHOTGUN_RELOAD_SOUND)); reloadSound = ShooterConsts::SHOTGUN_RELOAD_SOUND;
//reloadSound.setVolume(30); //reloadSound.setVolume(30);
_initialPack = 15; _initialPack = 15;

View File

@ -19,15 +19,13 @@ Weapon::Weapon(const std::string& weaponName, const std::string& objFileName, co
setCollider(false); setCollider(false);
rotate(r); rotate(r);
translate(t); translate(t);
noAmmoSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::NO_AMMO_SOUND));
} }
std::map<ObjectNameTag, double> Weapon::fire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction) { std::map<ObjectNameTag, double> Weapon::fire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction) {
if(_clipAmmo == 0) { if(_clipAmmo == 0) {
reload(); reload();
if(_clipAmmo == 0) if(_clipAmmo == 0)
noAmmoSound.play(); SoundController::playSound(SoundTag("noAmmo"), ShooterConsts::NO_AMMO_SOUND);
} }
if(_clipAmmo <= 0 || std::abs(Time::time() - _lastFireTime) < _fireDelay || std::abs(Time::time() - _lastReloadTime) < _reloadTime) if(_clipAmmo <= 0 || std::abs(Time::time() - _lastFireTime) < _fireDelay || std::abs(Time::time() - _lastReloadTime) < _reloadTime)
@ -36,7 +34,7 @@ std::map<ObjectNameTag, double> Weapon::fire(std::function<std::pair<Vec3D, Obje
_lastFireTime = Time::time(); _lastFireTime = Time::time();
_clipAmmo--; _clipAmmo--;
fireSound.play(); SoundController::playSound(SoundTag("fire"), fireSound);
Log::log("Weapon::fire (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")"); Log::log("Weapon::fire (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")");
return processFire(std::move(rayCastFunction)); return processFire(std::move(rayCastFunction));
@ -53,7 +51,7 @@ void Weapon::reload() {
_stockAmmo = 0; _stockAmmo = 0;
} }
reloadSound.play(); SoundController::playSound(SoundTag("fire"), reloadSound);
Log::log("Weapon::reload (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")"); Log::log("Weapon::reload (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")");
_lastReloadTime = Time::time(); _lastReloadTime = Time::time();
} }

View File

@ -12,7 +12,7 @@
#include <SFML/Audio/Sound.hpp> #include <SFML/Audio/Sound.hpp>
#include "../engine/Mesh.h" #include "../engine/Mesh.h"
#include "../engine/utils/Time.h" #include "../engine/utils/Time.h"
#include "../engine/SoundController.h"
#include "../engine/Consts.h" #include "../engine/Consts.h"
class Weapon : public RigidBody { class Weapon : public RigidBody {
@ -34,11 +34,8 @@ protected:
double _lastFireTime = std::numeric_limits<double>::min(); double _lastFireTime = std::numeric_limits<double>::min();
double _lastReloadTime = std::numeric_limits<double>::min(); double _lastReloadTime = std::numeric_limits<double>::min();
sf::Sound fireSound; std::string fireSound;
sf::Sound reloadSound; std::string reloadSound;
sf::Sound noAmmoSound;
int fireTraces = 0;
std::function<void(const Vec3D&, const Vec3D&)> _addTraceCallBack; std::function<void(const Vec3D&, const Vec3D&)> _addTraceCallBack;