diff --git a/assets/menu/sounds/music.wav b/assets/menu/sounds/music.wav new file mode 100644 index 0000000..a272f04 Binary files /dev/null and b/assets/menu/sounds/music.wav differ diff --git a/assets/snake/death.wav b/assets/snake/death.wav new file mode 100644 index 0000000..bba6b2a Binary files /dev/null and b/assets/snake/death.wav differ diff --git a/assets/snake/down.wav b/assets/snake/down.wav new file mode 100644 index 0000000..76ee628 Binary files /dev/null and b/assets/snake/down.wav differ diff --git a/assets/snake/eat.wav b/assets/snake/eat.wav new file mode 100644 index 0000000..7801d73 Binary files /dev/null and b/assets/snake/eat.wav differ diff --git a/assets/snake/effects.wav b/assets/snake/effects.wav new file mode 100644 index 0000000..0ad2d8d Binary files /dev/null and b/assets/snake/effects.wav differ diff --git a/assets/snake/left.wav b/assets/snake/left.wav new file mode 100644 index 0000000..24e462f Binary files /dev/null and b/assets/snake/left.wav differ diff --git a/assets/snake/right.wav b/assets/snake/right.wav new file mode 100644 index 0000000..a214ccf Binary files /dev/null and b/assets/snake/right.wav differ diff --git a/assets/snake/up.wav b/assets/snake/up.wav new file mode 100644 index 0000000..22d6c27 Binary files /dev/null and b/assets/snake/up.wav differ diff --git a/core/src/Core.cpp b/core/src/Core.cpp index 6c08ddb..facb377 100644 --- a/core/src/Core.cpp +++ b/core/src/Core.cpp @@ -303,6 +303,9 @@ void Core::_changeGameProvider(const unsigned char &index) } auto newProvider = this->_getGameProvider(index); this->_gameProvider = newProvider; + this->_textures.clear(); + this->_fonts.clear(); + this->_sounds.clear(); this->_initGame(); this->_initWindow(); } @@ -376,9 +379,18 @@ void Core::_handleMouseMove(std::shared_ptr &event, std::sh component->onMouseHover(this->_game); } +void Core::_stopAllGraphicsSounds() +{ + for (auto &sound : this->_sounds) { + sound.second.sound->setState(ISound::SoundState::PAUSE); + sound.second.previousGameState = components::PAUSE; + } +} + void Core::_handleWindowClose() { if (this->_window && this->_window->isOpen()) { + this->_stopAllGraphicsSounds(); this->_window->close(); this->_menu.updateScore(this->_game); } @@ -478,11 +490,13 @@ void Core::_handleSoundComponent(std::shared_ptr &g gameSound->onStateChange(this->_game, components::PAUSE); if (graphicSoundState == ISound::SoundState::STOP) gameSound->onStateChange(this->_game, components::STOP); + sound.previousGraphicState = graphicSoundState; } if (gameSoundVolume != graphicSoundVolume) sound.sound->setVolume(gameSoundVolume); if (gameSoundLoop != graphicSoundLoop) sound.sound->setLoopState(gameSoundLoop); + this->_sounds[gameSoundPath] = sound; } void Core::_handleComponentEvents(std::vector &events, std::shared_ptr &component) diff --git a/core/src/Core.hpp b/core/src/Core.hpp index 2b467ec..461ba3d 100644 --- a/core/src/Core.hpp +++ b/core/src/Core.hpp @@ -247,6 +247,12 @@ class Core { */ void _handleWindowClose(); + /** + * @brief Stop all sounds + * + */ + void _stopAllGraphicsSounds(); + /** * @brief Handle the window resize event * diff --git a/core/src/menu/Menu.cpp b/core/src/menu/Menu.cpp index 4b852a7..c701fca 100644 --- a/core/src/menu/Menu.cpp +++ b/core/src/menu/Menu.cpp @@ -19,6 +19,7 @@ Menu::Menu(GameProviders &gameProviders, GraphicsProviders &graphicsProviders, this->_score.score = 0; this->_readScores(); this->_textType = GAME; + this->_music = nullptr; } Menu::~Menu() @@ -148,11 +149,16 @@ void Menu::_initNoGameFound() void Menu::_initCheckBoxesGames() { - auto texture = this->_graphicsProvider->createTexture("assets/menu/img/space-invader.png", "assets/menu/img/space-invader.ascii"); + std::shared_ptr texture = nullptr; auto font = this->_font; float index = 9.0; int count = 0; + try { + texture = this->_graphicsProvider->createTexture("assets/menu/img/space-invader.png", "assets/menu/img/space-invader.ascii"); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + } for (auto gameProvider : this->_gameProviders) { if (count > 5) break; @@ -206,11 +212,16 @@ void Menu::_initHiddenGraphics(const GraphicsManifest &graphicsManifest, std::sh void Menu::_initCheckBoxesGraphics() { - auto texture = this->_graphicsProvider->createTexture("assets/menu/img/space-invader.png", "assets/menu/img/space-invader.ascii"); + std::shared_ptr texture = nullptr; auto font = this->_font; float index = 17.0; int count = 0; + try { + texture = this->_graphicsProvider->createTexture("assets/menu/img/space-invader.png", "assets/menu/img/space-invader.ascii"); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + } for (auto graphicsProvider : this->_graphicsProviders) { if (count > 5) break; @@ -230,12 +241,16 @@ void Menu::_initCheckBoxesGraphics() void Menu::_initTextures() { - auto backgroundTexture = this->_graphicsProvider->createTexture("assets/menu/img/background.png", "assets/menu/img/background.ascii"); - this->_textures.push_back(std::make_shared(backgroundTexture, Vector2f{12, 12}, Vector2u{0, 0}, Vector2u{50, 25}, Vector2f{0, 0})); - auto titleTexture = this->_graphicsProvider->createTexture("assets/menu/img/title.png", "assets/menu/img/title.ascii"); - this->_textures.push_back(std::make_shared(titleTexture, Vector2f{17, 17}, Vector2u{0, 0}, Vector2u{31, 5}, Vector2f{10, 1})); - auto middleTexture = this->_graphicsProvider->createTexture("assets/menu/img/middle.png", "assets/menu/img/middle.ascii"); - this->_textures.push_back(std::make_shared(middleTexture, Vector2f{12, 12}, Vector2u{0, 0}, Vector2u{1, 15}, Vector2f{24, 7})); + try { + auto backgroundTexture = this->_graphicsProvider->createTexture("assets/menu/img/background.png", "assets/menu/img/background.ascii"); + this->_textures.push_back(std::make_shared(backgroundTexture, Vector2f{12, 12}, Vector2u{0, 0}, Vector2u{50, 25}, Vector2f{0, 0})); + auto titleTexture = this->_graphicsProvider->createTexture("assets/menu/img/title.png", "assets/menu/img/title.ascii"); + this->_textures.push_back(std::make_shared(titleTexture, Vector2f{17, 17}, Vector2u{0, 0}, Vector2u{31, 5}, Vector2f{10, 1})); + auto middleTexture = this->_graphicsProvider->createTexture("assets/menu/img/middle.png", "assets/menu/img/middle.ascii"); + this->_textures.push_back(std::make_shared(middleTexture, Vector2f{12, 12}, Vector2u{0, 0}, Vector2u{1, 15}, Vector2f{24, 7})); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + } } void Menu::_initTexts() @@ -269,6 +284,14 @@ void Menu::_preventGraphicsProvider() std::cout << "No graphics provider found, using default provider" << std::endl; } +void Menu::_initMusic() +{ + this->_music = this->_graphicsProvider->createSound("assets/menu/sounds/music.wav"); + this->_music->setVolume(50); + this->_music->setLoopState(true); + this->_music->setState(ISound::SoundState::PLAY); +} + void Menu::_initWindow() { IWindow::WindowInitProps windowInitProps { @@ -279,13 +302,18 @@ void Menu::_initWindow() .icon = "assets/menu/img/icon.png" }; - this->_clearLists(); - this->_preventGraphicsProvider(); - this->_initTexts(); - this->_initTextures(); - this->_initCheckBoxesGames(); - this->_initCheckBoxesGraphics(); - this->_window = this->_graphicsProvider->createWindow(windowInitProps); + try { + this->_window = this->_graphicsProvider->createWindow(windowInitProps); + this->_clearLists(); + this->_preventGraphicsProvider(); + this->_initTexts(); + this->_initTextures(); + this->_initCheckBoxesGames(); + this->_initCheckBoxesGraphics(); + this->_initMusic(); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + } } void Menu::_handleSelectUpperCheckBox() @@ -342,7 +370,7 @@ void Menu::_handleSelectLowerCheckBox() this->_checkBoxType = GRAPHICS_CHECKBOX; } else { this->_gamesCheckBoxes.at(index + 1)->hover(); - } + } break; } } @@ -512,6 +540,8 @@ void Menu::_handleEvents() void Menu::_renderField() { + if (!this->_font) + return; if (this->_score.player.empty()) { auto placeholder = std::make_shared(this->_font, 30, "Guest", TextAlign::CENTER, TextVerticalAlign::MIDDLE, Color{255, 255, 255, 255}, Vector2u{16, 1}, Vector2f{17, 23}); this->_nameField = placeholder; @@ -560,6 +590,8 @@ void Menu::_render() void Menu::_previousSelectedGame() { this->_checkBoxType = GAME_CHECKBOX; + if (this->_gamesCheckBoxes.empty()) + return; for (auto gameProvider : this->_gameProviders) { if (this->_gameProvider == gameProvider.second) { auto index = std::distance(this->_gameProviders.begin(), std::find(this->_gameProviders.begin(), this->_gameProviders.end(), gameProvider)); @@ -579,6 +611,8 @@ void Menu::_previousSelectedGame() void Menu::_previousSelectedGraphics() { + if (this->_graphicsCheckBoxes.empty()) + return; for (auto graphicsProvider : this->_graphicsProviders) { if (this->_graphicsProvider == graphicsProvider.second) { auto index = std::distance(this->_graphicsProviders.begin(), std::find(this->_graphicsProviders.begin(), this->_graphicsProviders.end(), graphicsProvider)); @@ -608,10 +642,14 @@ void Menu::run() this->_initWindow(); this->_previousSelectedGame(); this->_previousSelectedGraphics(); + if (!this->_window) + throw ArcadeError("Can't create window"); while (this->_window->isOpen()) { this->_handleEvents(); this->_render(); } + if (this->_music) + this->_music->setState(ISound::SoundState::STOP); } void Menu::_readScores() diff --git a/core/src/menu/Menu.hpp b/core/src/menu/Menu.hpp index 8ff12d8..8b77dbb 100644 --- a/core/src/menu/Menu.hpp +++ b/core/src/menu/Menu.hpp @@ -81,6 +81,7 @@ class Menu { std::map, std::vector>> _hiddenAuthors; std::shared_ptr _font; std::shared_ptr _nameField; + std::shared_ptr _music; /** * @brief Initialize the window @@ -193,6 +194,12 @@ class Menu { */ void _initTextures(); + /** + * @brief Initialize Background Music + * + */ + void _initMusic(); + /** * @brief Initialize hidden textures * diff --git a/core/src/menu/entity/text/Text.cpp b/core/src/menu/entity/text/Text.cpp index 5d181fe..ded76d3 100644 --- a/core/src/menu/entity/text/Text.cpp +++ b/core/src/menu/entity/text/Text.cpp @@ -28,7 +28,11 @@ void Text::draw(std::shared_ptr window) .position = this->_position }; - window->render(textProps); + try { + window->render(textProps); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + } } void Text::setColor(Color color) diff --git a/core/src/menu/entity/texture/Texture.cpp b/core/src/menu/entity/texture/Texture.cpp index 2df1bb1..64d088e 100644 --- a/core/src/menu/entity/texture/Texture.cpp +++ b/core/src/menu/entity/texture/Texture.cpp @@ -23,7 +23,11 @@ void Texture::draw(std::shared_ptr window) .position = this->_position }; - window->render(textureProps); + try { + window->render(textureProps); + } catch (const std::exception &e) { + std::cerr << e.what() << std::endl; + } } void Texture::setOrigin(Vector2u origin) diff --git a/games/common/CMakeLists.txt b/games/common/CMakeLists.txt index 87ef00d..422c7c7 100644 --- a/games/common/CMakeLists.txt +++ b/games/common/CMakeLists.txt @@ -13,5 +13,7 @@ target_sources(${PROJECT_NAME} PUBLIC components/CollidableComponent.cpp components/TextureComponent.hpp components/TextureComponent.cpp + components/SoundComponent.hpp + components/SoundComponent.cpp ) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../..) diff --git a/games/common/components/SoundComponent.cpp b/games/common/components/SoundComponent.cpp new file mode 100644 index 0000000..b5df63b --- /dev/null +++ b/games/common/components/SoundComponent.cpp @@ -0,0 +1,50 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** SoundComponent +*/ + +#include "SoundComponent.hpp" + +using namespace shared::games::components; +using namespace arcade::games::common::components; + +SoundComponent::SoundComponent(shared::games::entity::IEntity &entity, const std::string &path, + shared::games::components::SoundState state, shared::games::components::SoundVolume volume, bool loop, onChangeFunction onChange) + : AComponent(SOUND, entity), _path(path), _state(state), _volume(volume), _loop(loop), _onChange(onChange) +{ + this->_type = SOUND; +} + +const std::string &SoundComponent::getPath() const noexcept +{ + return this->_path; +} + +SoundState &SoundComponent::getState() noexcept +{ + return this->_state; +} + +SoundVolume &SoundComponent::getVolume() noexcept +{ + return this->_volume; +} + +bool &SoundComponent::getLoop() noexcept +{ + return this->_loop; +} + +void SoundComponent::onStateChange(std::shared_ptr ctx, + shared::games::components::SoundState state) +{ + if (this->_onChange) + this->_onChange(ctx, state); +} + +void SoundComponent::setState(SoundState state) +{ + this->_state = state; +} diff --git a/games/common/components/SoundComponent.hpp b/games/common/components/SoundComponent.hpp new file mode 100644 index 0000000..08c414d --- /dev/null +++ b/games/common/components/SoundComponent.hpp @@ -0,0 +1,78 @@ +/* +** EPITECH PROJECT, 2024 +** arcade +** File description: +** SoundComponent +*/ + +#pragma once + +#include "AComponent.hpp" +#include "shared/games/components/ISoundComponent.hpp" + +namespace arcade::games::common::components +{ + class SoundComponent; +} + +class arcade::games::common::components::SoundComponent + : public virtual shared::games::components::ISoundComponent, public AComponent +{ +public: + typedef void (*onChangeFunction)(std::shared_ptr ctx, shared::games::components::SoundState state); + + ~SoundComponent() override = default; + + explicit SoundComponent(shared::games::entity::IEntity &entity, const std::string &path, + shared::games::components::SoundState state, shared::games::components::SoundVolume volume, bool loop, onChangeFunction onChange = nullptr); + + /** + * @brief Get path of the sound + * + * @return Sound path + */ + const std::string &getPath() const noexcept override; + + /** + * @brief Get state of the sound + * + * @return Sound state + */ + shared::games::components::SoundState &getState() noexcept override; + + /** + * @brief Get volume of the sound + * + * @return Sound volume + */ + shared::games::components::SoundVolume &getVolume() noexcept override; + + /** + * @brief Get loop of the sound + * + * @return Sound loop + */ + bool &getLoop() noexcept override; + + /** + * @brief On state change event handler for the component + * + * @param ctx Context of the game + * @param state New state of the sound + */ + void onStateChange(std::shared_ptr ctx, shared::games::components::SoundState state) override; + + /** + * @brief Set the state of the sound + * + * @param state New state of the sound + */ + void setState(shared::games::components::SoundState state); + +protected: + std::string _path; + shared::games::components::SoundState _state; + shared::games::components::SoundVolume _volume; + onChangeFunction _onChange; + bool _loop; +}; diff --git a/games/snake/src/SnakeGame.cpp b/games/snake/src/SnakeGame.cpp index 248685e..a2be7f0 100644 --- a/games/snake/src/SnakeGame.cpp +++ b/games/snake/src/SnakeGame.cpp @@ -29,6 +29,11 @@ const shared::games::GameManifest snake::SnakeGame::manifest = { .name = "Flavien Chenu", .email = "flavienchenu@epitech.eu", .website = "https://github.com/flavien-chenu" + }, + { + .name = "Yann Masson", + .email = "yannmasson@epitech.eu", + .website = "yannmasson.fr" } } }; @@ -51,6 +56,7 @@ snake::SnakeGame::SnakeGame() : common::AGame(Vector2u(20, 20), 60) { this->_looseGame = false; this->speedTime = 100; this->speedBoost = 0; + this->moved = false; } const shared::games::GameManifest &snake::SnakeGame::getManifest() const noexcept { @@ -70,6 +76,7 @@ void snake::SnakeGame::compute(shared::games::DeltaTime dt) { } if (this->_clock > std::chrono::milliseconds(speed) + this->_snake->lastMove) { this->_snake->lastMove = this->_clock; + this->moved = false; this->_snake->forward(); } } @@ -89,18 +96,37 @@ void snake::SnakeGame::_loose() { } this->_looseGame = false; - this->_score = 0; + if (this->_score < this->_currentScore) + this->_score = this->_currentScore; + this->_apple->generateApple(); + this->speedTime = 100; } void snake::SnakeGame::setLooseGame(bool state) { this->_looseGame = state; } +void snake::SnakeGame::changeStateSound(const std::string &soundName, shared::games::components::SoundState state) { + for (auto &entity: this->_entities) { + auto head = std::dynamic_pointer_cast(entity); + if (head == nullptr) + continue; + auto components = head->getComponents(); + for (auto &component: components) { + auto sound = std::dynamic_pointer_cast(component); + if (sound == nullptr) + continue; + sound->sounds[soundName]->setState(state); + } + } +} + void snake::SnakeGame::addNewPoint() { std::shared_ptr newTail = this->_snake->addTail(); + this->changeStateSound("eat", shared::games::components::SoundState::PLAY); this->_registerEntity(newTail); this->_apple->generateApple(); this->speedTime -= 2; - this->_score += 10; + this->_currentScore += 10; } diff --git a/games/snake/src/SnakeGame.hpp b/games/snake/src/SnakeGame.hpp index 24d6e3c..4746b6b 100644 --- a/games/snake/src/SnakeGame.hpp +++ b/games/snake/src/SnakeGame.hpp @@ -10,6 +10,7 @@ #include "common/game/AGame.hpp" #include "games/snake/src/entities/snake/Snake.hpp" #include "entities/apple/AppleEntity.hpp" +#include "common/components/SoundComponent.hpp" namespace arcade::games::snake { class SnakeGame; @@ -53,10 +54,20 @@ class arcade::games::snake::SnakeGame : public arcade::games::common::AGame { */ void addNewPoint(); + /** + * @brief Change the state of a sound + * + * @param soundName Name of the sound + * @param state State of the sound + */ + void changeStateSound(const std::string &soundName, shared::games::components::SoundState state); + unsigned int speedTime; unsigned int speedBoost; + bool moved; + protected: /** * @brief Execute the process of the end of the game when the player _loose @@ -67,4 +78,5 @@ class arcade::games::snake::SnakeGame : public arcade::games::common::AGame { std::shared_ptr _apple; shared::games::DeltaTime _clock; bool _looseGame; + int _currentScore; }; diff --git a/games/snake/src/entities/snake/HeadEntity.cpp b/games/snake/src/entities/snake/HeadEntity.cpp index e744697..687ccf8 100644 --- a/games/snake/src/entities/snake/HeadEntity.cpp +++ b/games/snake/src/entities/snake/HeadEntity.cpp @@ -23,7 +23,11 @@ arcade::games::snake::HeadEntity::HeadEntity() : _textureProps( this->_textureProps); std::shared_ptr keyboard = std::make_shared( *this); + auto keyboardSounds = keyboard->sounds; + for (auto &sound: keyboardSounds) { + this->_components.push_back(sound.second); + } this->_components.push_back(collide); this->_components.push_back(texture); this->_components.push_back(keyboard); @@ -72,6 +76,7 @@ void arcade::games::snake::HeadEntity::_onCollide(std::shared_ptr(&target->getEntity()) || dynamic_cast(&target->getEntity())) { + game->changeStateSound("death", SoundState::PLAY); game->setLooseGame(true); } } diff --git a/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp index f0f0efd..dc774ee 100644 --- a/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp +++ b/games/snake/src/entities/snake/components/HeadKeyboardComponent.cpp @@ -8,47 +8,144 @@ #include "HeadKeyboardComponent.hpp" #include "../../../SnakeGame.hpp" +using namespace arcade::games::common::components; using namespace arcade::games::snake::components; using namespace shared::games::components; -HeadKeyboardComponent::HeadKeyboardComponent(HeadEntity &entity) : AComponent(KEYBOARD, entity), _parent(entity) {} +HeadKeyboardComponent::HeadKeyboardComponent(HeadEntity &entity) : AComponent(KEYBOARD, entity), _parent(entity), _previousDirection(1, 0) +{ + auto up = std::make_shared(this->_parent, "assets/snake/up.wav", SoundState::STOP, 100, false, HeadKeyboardComponent::_onSoundStateChangeUp); + this->sounds["up"] = up; + auto down = std::make_shared(this->_parent, "assets/snake/down.wav", SoundState::STOP, 100, false, HeadKeyboardComponent::_onSoundStateChangeDown); + this->sounds["down"] = down; + auto left = std::make_shared(this->_parent, "assets/snake/left.wav", SoundState::STOP, 100, false, HeadKeyboardComponent::_onSoundStateChangeLeft); + this->sounds["left"] = left; + auto right = std::make_shared(this->_parent, "assets/snake/right.wav", SoundState::STOP, 100, false, HeadKeyboardComponent::_onSoundStateChangeRight); + this->sounds["right"] = right; + auto eat = std::make_shared(this->_parent, "assets/snake/eat.wav", SoundState::STOP, 100, false, HeadKeyboardComponent::_onSoundStateChangeEat); + this->sounds["eat"] = eat; + auto death = std::make_shared(this->_parent, "assets/snake/death.wav", SoundState::STOP, 100, false, HeadKeyboardComponent::_onSoundStateChangeDeath); + this->sounds["death"] = death; +} void HeadKeyboardComponent::onKeyPress(std::shared_ptr ctx, - shared::games::components::IKeyboardComponent::KeyData keyData) { - if (keyData.type == ARROW) { + shared::games::components::IKeyboardComponent::KeyData keyData) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (!game->moved && keyData.type == ARROW) { if (keyData.code.arrow == UP && this->_parent.direction.y != 1) { this->_parent.direction = Vector2i(0, -1); + this->_playSound("up"); } if (keyData.code.arrow == DOWN && this->_parent.direction.y != -1) { this->_parent.direction = Vector2i(0, 1); + this->_playSound("down"); } if (keyData.code.arrow == LEFT && this->_parent.direction.x != 1) { this->_parent.direction = Vector2i(-1, 0); + this->_playSound("left"); } if (keyData.code.arrow == RIGHT && this->_parent.direction.x != -1) { this->_parent.direction = Vector2i(1, 0); + this->_playSound("right"); } + game->moved = true; } - if (keyData.type == CHAR) { + if (!game->moved && keyData.type == CHAR) { if (keyData.code.character == 'z' && this->_parent.direction.y != 1) { this->_parent.direction = Vector2i(0, -1); + this->_playSound("up"); } if (keyData.code.character == 's' && this->_parent.direction.y != -1) { this->_parent.direction = Vector2i(0, 1); + this->_playSound("down"); } if (keyData.code.character == 'q' && this->_parent.direction.x != 1) { this->_parent.direction = Vector2i(-1, 0); + this->_playSound("left"); } if (keyData.code.character == 'd' && this->_parent.direction.x != -1) { this->_parent.direction = Vector2i(1, 0); + this->_playSound("right"); } + game->moved = true; } if (keyData.type == CHAR && keyData.code.character == ' ') { - auto game = std::dynamic_pointer_cast(ctx); - game->speedBoost = 3; } } void HeadKeyboardComponent::onKeyRelease(std::shared_ptr ctx, shared::games::components::IKeyboardComponent::KeyData keyData) {} + +void HeadKeyboardComponent::_playSound(const std::string &soundName) +{ + if (this->_previousDirection.x != this->_parent.direction.x && + this->_previousDirection.y != this->_parent.direction.y) { + this->sounds[soundName]->setState(shared::games::components::SoundState::PLAY); + } + this->_previousDirection = this->_parent.direction; +} + +void HeadKeyboardComponent::_onSoundStateChangeUp(std::shared_ptr ctx, shared::games::components::SoundState state) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (state == shared::games::components::SoundState::STOP) + game->changeStateSound("up", shared::games::components::SoundState::STOP); +} + +void HeadKeyboardComponent::_onSoundStateChangeDown(std::shared_ptr ctx, shared::games::components::SoundState state) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (state == shared::games::components::SoundState::STOP) + game->changeStateSound("down", shared::games::components::SoundState::STOP); +} + +void HeadKeyboardComponent::_onSoundStateChangeLeft(std::shared_ptr ctx, shared::games::components::SoundState state) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (state == shared::games::components::SoundState::STOP) + game->changeStateSound("left", shared::games::components::SoundState::STOP); +} + +void HeadKeyboardComponent::_onSoundStateChangeRight(std::shared_ptr ctx, shared::games::components::SoundState state) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (state == shared::games::components::SoundState::STOP) + game->changeStateSound("right", shared::games::components::SoundState::STOP); +} + +void HeadKeyboardComponent::_onSoundStateChangeEat(std::shared_ptr ctx, shared::games::components::SoundState state) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (state == shared::games::components::SoundState::STOP) + game->changeStateSound("eat", shared::games::components::SoundState::STOP); +} + +void HeadKeyboardComponent::_onSoundStateChangeDeath(std::shared_ptr ctx, shared::games::components::SoundState state) +{ + auto game = std::dynamic_pointer_cast(ctx); + + if (!game) + return; + if (state == shared::games::components::SoundState::STOP) + game->changeStateSound("death", shared::games::components::SoundState::STOP); +} diff --git a/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp b/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp index 5f42113..2791575 100644 --- a/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp +++ b/games/snake/src/entities/snake/components/HeadKeyboardComponent.hpp @@ -7,10 +7,13 @@ #pragma once +#include #include "shared/games/components/IKeyboardComponent.hpp" #include "common/components/AComponent.hpp" #include "../HeadEntity.hpp" +#include "common/components/SoundComponent.hpp" + namespace arcade::games::snake::components { class HeadKeyboardComponent; } @@ -40,6 +43,62 @@ class arcade::games::snake::components::HeadKeyboardComponent */ void onKeyRelease(std::shared_ptr ctx, shared::games::components::IKeyboardComponent::KeyData keyData) override; + /** + * @brief Map of sounds + * + */ + std::map> sounds; protected: HeadEntity &_parent; + Vector2i _previousDirection; + + void _playSound(const std::string &soundName); + + /** + * @brief On sound state change event UP + * + * @param ctx Game context + * @param state new state of the sound + */ + static void _onSoundStateChangeUp(std::shared_ptr ctx, shared::games::components::SoundState state); + + /** + * @brief On sound state change event DOWN + * + * @param ctx Game context + * @param state new state of the sound + */ + static void _onSoundStateChangeDown(std::shared_ptr ctx, shared::games::components::SoundState state); + + /** + * @brief On sound state change event LEFT + * + * @param ctx Game context + * @param state new state of the sound + */ + static void _onSoundStateChangeLeft(std::shared_ptr ctx, shared::games::components::SoundState state); + + /** + * @brief On sound state change event RIGHT + * + * @param ctx Game context + * @param state new state of the sound + */ + static void _onSoundStateChangeRight(std::shared_ptr ctx, shared::games::components::SoundState state); + + /** + * @brief On sound state change event EAT + * + * @param ctx Game context + * @param state new state of the sound + */ + static void _onSoundStateChangeEat(std::shared_ptr ctx, shared::games::components::SoundState state); + + /** + * @brief On sound state change event DEATH + * + * @param ctx Game context + * @param state new state of the sound + */ + static void _onSoundStateChangeDeath(std::shared_ptr ctx, shared::games::components::SoundState state); }; diff --git a/graphics/sfml/src/window/Window.cpp b/graphics/sfml/src/window/Window.cpp index 28a14a4..3122d32 100644 --- a/graphics/sfml/src/window/Window.cpp +++ b/graphics/sfml/src/window/Window.cpp @@ -15,7 +15,6 @@ using namespace arcade::graphics::common::exceptions; const Vector2u Window::tileSize = { 35, 35 }; -#include Window::Window(const IWindow::WindowInitProps &props): _size(props.size), _initialSize(0, 0),