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

View File

@ -82,15 +82,15 @@ void Client::processCustomPacket(MsgType type, sf::Packet& packet) {
_player->addDeath();
// 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->playDeath();
_player->initWeapons();
_player->setFullAbility();
SoundController::playSound(SoundTag("death"), ShooterConsts::DEATH_SOUND);
}
else
_players[buffId[0]]->addDeath();
if(buffId[1] == _socket.ownId()) {
_player->addKill();
_player->playKill();
SoundController::playSound(SoundTag("kill"), ShooterConsts::KILL_SOUND);
}
else
_players[buffId[1]]->addKill();

View File

@ -14,11 +14,6 @@ Player::Player() {
setVisible(false);
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);});
}
@ -27,16 +22,6 @@ void Player::rotateWeaponsRelativePoint(const Vec3D& point4D, const Vec3D& v, do
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) {
if(tag.str().find("Bonus_gun") != std::string::npos)
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) {
_changeWeaponSound.play();
SoundController::playSound(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
for(auto& w : _weapons) {
if (w->name() == weapon->name()) {
@ -106,7 +91,7 @@ void Player::nextWeapon() {
_selectedWeapon = (_selectedWeapon + 1) % _weapons.size();
_addWeaponCallBack(_weapons[_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;
_addWeaponCallBack(_weapons[_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() {
_health = ShooterConsts::HEALTH_MAX;
_fullHealthSound.play();
SoundController::playSound(SoundTag("addHealth"), ShooterConsts::RESTORE_HEALTH_SOUND);
}
void Player::setFullAbility() {
_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 _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;
size_t _selectedWeapon = 0;
@ -48,12 +41,8 @@ private:
public:
Player();
void setHealth(double h) {
_health = h;
}
void setAbility(double a) {
_ability = a;
}
void setHealth(double h) { _health = h; }
void setAbility(double a) { _ability = a; }
[[nodiscard]] double health() const { return _health; }
[[nodiscard]] double ability() const { return _ability; }
@ -79,9 +68,6 @@ public:
void addKill() { _kills++; }
void addDeath() { _deaths++; }
void playDeath();
void playKill();
void setDamagePlayerCallBack(std::function<void(sf::Uint16 targetId, double)> hit) {
_damagePlayerCallBack = std::move(hit);
}

View File

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

View File

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

View File

@ -9,6 +9,7 @@
#include "engine/animation/ARotate.h"
#include "engine/animation/Timeline.h"
#include "ShooterConsts.h"
#include "engine/SoundController.h"
using namespace std;
@ -96,10 +97,10 @@ void Shooter::start() {
mainMenu.title("Main menu");
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, 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, 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(); 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
InitNetwork();
@ -144,10 +145,8 @@ void Shooter::update() {
setUpdateWorld(inGame);
// background sounds and music control
if(backgroundNoise.getStatus() != sf::Sound::Status::Playing) {
backgroundNoise.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::BACK_NOISE));
backgroundNoise.play();
}
if(SoundController::getStatus(SoundTag("background")) != sf::Sound::Status::Playing)
SoundController::playSound(SoundTag("background"), ShooterConsts::BACK_NOISE);
}
void Shooter::gui() {

View File

@ -24,6 +24,7 @@ namespace Consts {
const std::string THIN_FONT = "engine/fonts/Roboto-Thin.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 unsigned NETWORK_VERSION = 1U;

View File

@ -7,8 +7,14 @@
#include <iostream>
#include "ResourceManager.h"
#include "animation/Timeline.h"
#include "SoundController.h"
Engine::Engine() {
Time::init();
Timeline::init();
ResourceManager::init();
SoundController::init();
screen = std::make_shared<Screen>();
keyboard = std::make_shared<Keyboard>();
mouse = std::make_shared<Mouse>();
@ -64,14 +70,17 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name,
screen->display();
}
exit();
}
void Engine::exit() {
if(screen->isOpen()) {
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 '" +
screen->title() + "'.");
}

View File

@ -6,47 +6,43 @@
#include <map>
#include <memory>
namespace ResourceManager
{
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;
ResourceManager* ResourceManager::_instance = nullptr;
void ResourceManager::init() {
_instance = new ResourceManager();
}
void unloadTextures()
{
for (auto & _texture : _textures)
void ResourceManager::unloadTextures() {
for (auto & _texture : _instance->_textures)
_texture.second.reset();
_textures.clear();
_instance->_textures.clear();
}
void unloadSoundBuffers()
{
for (auto & _soundBuffer : _soundBuffers)
void ResourceManager::unloadSoundBuffers() {
for (auto & _soundBuffer : _instance->_soundBuffers)
_soundBuffer.second.reset();
_soundBuffers.clear();
_instance->_soundBuffers.clear();
}
void unloadFonts() {
for (auto & _font : _fonts)
void ResourceManager::unloadFonts() {
for (auto & _font : _instance->_fonts)
_font.second.reset();
_fonts.clear();
_instance->_fonts.clear();
}
void unloadAllResources()
{
void ResourceManager::unloadAllResources() {
unloadTextures();
unloadSoundBuffers();
unloadFonts();
}
std::shared_ptr<sf::Texture> loadTexture(const std::string& filename)
{
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 = _textures.find(filename);
if (it != _textures.end())
auto it = _instance->_textures.find(filename);
if (it != _instance->_textures.end())
return it->second;
// Otherwise - try to load it. If failure - return zero
@ -56,16 +52,18 @@ namespace ResourceManager
// If success - remember and return texture pointer
texture->setRepeated(true);
_textures.emplace(filename, texture);
_instance->_textures.emplace(filename, texture);
return texture;
}
std::shared_ptr<sf::SoundBuffer> loadSoundBuffer(const std::string& filename)
{
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 = _soundBuffers.find(filename);
if (it != _soundBuffers.end())
auto it = _instance->_soundBuffers.find(filename);
if (it != _instance->_soundBuffers.end())
return it->second;
// Otherwise - try to load it. If failure - return zero
@ -74,15 +72,18 @@ namespace ResourceManager
return nullptr;
// If success - remember and return texture pointer
_soundBuffers.emplace(filename, soundBuffer);
_instance->_soundBuffers.emplace(filename, soundBuffer);
return soundBuffer;
}
std::shared_ptr<sf::Font> loadFont(const std::string& filename) {
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 = _fonts.find(filename);
if (it != _fonts.end())
auto it = _instance->_fonts.find(filename);
if (it != _instance->_fonts.end())
return it->second;
// Otherwise - try to load it. If failure - return zero
@ -91,8 +92,14 @@ namespace ResourceManager
return nullptr;
// If success - remember and return texture pointer
_fonts.emplace(filename, font);
_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 <memory>
namespace ResourceManager
{
// Unloads all currently loaded textures.
void unloadTextures();
void unloadSoundBuffers();
void unloadFonts();
void unloadShaders();
class ResourceManager final {
private:
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 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.
// If success returns pointer to texture.
// Otherwise returns nullptr.
std::shared_ptr<sf::Texture> loadTexture(const std::string& filename);
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::Texture> loadTexture(const std::string& filename);
static std::shared_ptr<sf::Font> loadFont(const std::string& filename);
static std::shared_ptr<sf::SoundBuffer> loadSoundBuffer(const std::string& filename);
};
#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,30 +6,52 @@
#include "Animation.h"
#include "Timeline.h"
namespace Timeline {
namespace {
std::map<AnimationListTag, std::list<Animation*>> _animations;
Timeline* Timeline::_instance = nullptr;
void Timeline::init() {
_instance = new Timeline();
}
void animate(const AnimationListTag& listName, Animation* anim) {
_animations[listName].emplace_back(anim);
void Timeline::animate(const AnimationListTag& listName, Animation* anim) {
if(!_instance)
return;
_instance->_animations[listName].emplace_back(anim);
}
void deleteAllAnimations() {
_animations.clear();
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 deleteAnimationList(const AnimationListTag& listName) {
_animations[listName].clear();
_animations.erase(listName);
void Timeline::deleteAnimationList(const AnimationListTag& listName) {
if(!_instance)
return;
_instance->_animations[listName].clear();
_instance->_animations.erase(listName);
}
[[nodiscard]] bool isInAnimList(const AnimationListTag& listName) {
return !_animations[listName].empty();
[[nodiscard]] bool Timeline::isInAnimList(const AnimationListTag& listName) {
if(!_instance)
return false;
return !_instance->_animations[listName].empty();
}
void update() {
for (auto& [listName, animationList] : _animations) {
void Timeline::update() {
if(!_instance)
return;
for (auto& [listName, animationList] : _instance->_animations) {
if (animationList.empty())
continue;
@ -51,4 +73,10 @@ namespace Timeline {
}
}
}
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; }
};
namespace Timeline {
void update();
void animate(const AnimationListTag& listName, Animation* anim);
class Timeline {
private:
std::map<AnimationListTag, std::list<Animation*>> _animations;
void deleteAllAnimations();
void deleteAnimationList(const AnimationListTag& listName);
static Timeline* _instance;
[[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

View File

@ -32,7 +32,7 @@ void Button::press()
_button.setTextureRect(sf::IntRect(_pressedState.tx, _pressedState.ty, _w, _h));
if(_checkBox)
_pressed = true;
_clickSound.play();
//_clickSound.play();
_click();
}
else
@ -55,14 +55,14 @@ void Button::init() {
_text.setFillColor(_textColor);
_text.setPosition((float)(_x - _text.getLocalBounds().width / 2), (float)(_y - _h * _sy / 2 + _text.getLocalBounds().height / 4));
_clickSound.setBuffer(*ResourceManager::loadSoundBuffer(_clickSoundName));
_clickSound.setVolume(15);
//_clickSound.setBuffer(*ResourceManager::loadSoundBuffer(_clickSoundName));
//_clickSound.setVolume(15);
}
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,
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),
_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 <functional>
struct tPos {
int tx;
int ty;
struct tPos final {
const int tx;
const int ty;
};
class Button final {
@ -37,11 +37,8 @@ private:
std::string _font;
sf::Color _textColor;
std::string _clickSoundName;
sf::Sprite _button;
sf::Text _text;
sf::Sound _clickSound;
bool _selected = false;
bool _pressed = false;
@ -49,7 +46,7 @@ private:
public:
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 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,
const std::string &texture, tPos usualState, tPos selectedState, tPos pressedState,
const std::string& font, sf::Color textColor, const std::string& clickSound) {
_buttons.push_back(Button{x, y, w, h, std::move(click), text, sx, sy, texture, usualState, selectedState, pressedState, font, textColor, 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});
_buttons.back().init();
}

View File

@ -31,7 +31,7 @@ public:
std::function<void()> click,
const std::string& text = "_button", double sx = 1, double sy = 1,
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; }
void title(const std::string& title) { _name = title; }

View File

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

View File

@ -9,8 +9,8 @@
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}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::AK47_FIRE_SOUND));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::AK47_RELOAD_SOUND));
fireSound = ShooterConsts::AK47_FIRE_SOUND;
reloadSound = ShooterConsts::AK47_RELOAD_SOUND;
_stockAmmo = ammo - _clipCapacity;

View File

@ -11,8 +11,8 @@
class Gold_Ak47 final : public Weapon {
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}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::GOLD_AK47_FIRE_SOUND));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::GOLD_AK47_RELOAD_SOUND));
fireSound = ShooterConsts::GOLD_AK47_FIRE_SOUND;
reloadSound = ShooterConsts::GOLD_AK47_RELOAD_SOUND;
_initialPack = 200;
_spreading = 1.0;

View File

@ -9,8 +9,8 @@
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}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::GUN_FIRE_SOUND));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::GUN_RELOAD_SOUND));
fireSound = ShooterConsts::GUN_FIRE_SOUND;
reloadSound = ShooterConsts::GUN_RELOAD_SOUND;
_initialPack = 30;
_clipCapacity = 6; // how much ammo can be stored in one clip

View File

@ -7,8 +7,8 @@
#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}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RIFLE_FIRE_SOUND));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RIFLE_RELOAD_SOUND));
fireSound = ShooterConsts::RIFLE_FIRE_SOUND;
reloadSound = ShooterConsts::RIFLE_RELOAD_SOUND;
_initialPack = 5;
_clipCapacity = 1; // how much ammo can be stored in one clip

View File

@ -10,8 +10,8 @@
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}) {
fireSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::SHOTGUN_FIRE_SOUND));
reloadSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::SHOTGUN_RELOAD_SOUND));
fireSound = ShooterConsts::SHOTGUN_FIRE_SOUND;
reloadSound = ShooterConsts::SHOTGUN_RELOAD_SOUND;
//reloadSound.setVolume(30);
_initialPack = 15;

View File

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

View File

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