diff options
author | Vittorio Romeo <vittorio.romeo@outlook.com> | 2021-11-25 02:31:44 +0000 |
---|---|---|
committer | Vittorio Romeo <vittorio.romeo@outlook.com> | 2021-11-25 02:31:44 +0000 |
commit | 37a5fbf2d47782d039f38bb34837d4247ba0e16b (patch) | |
tree | bde27cd677bdd9a2361a234fa4ac4cea7260eb8a | |
parent | e810d924f3ac6c3c3418e0fbf7f09d1995984f3d (diff) |
Implement "swap ready sound", "swap particles", and "show swap blinking effect"
-rw-r--r-- | _RELEASE/Assets/assets.json | 3 | ||||
-rw-r--r-- | include/SSVOpenHexagon/Components/CPlayer.hpp | 4 | ||||
-rw-r--r-- | include/SSVOpenHexagon/Core/HexagonGame.hpp | 22 | ||||
-rw-r--r-- | src/SSVOpenHexagon/Components/CPlayer.cpp | 15 | ||||
-rw-r--r-- | src/SSVOpenHexagon/Core/HGGraphics.cpp | 17 | ||||
-rw-r--r-- | src/SSVOpenHexagon/Core/HGUpdate.cpp | 117 | ||||
-rw-r--r-- | src/SSVOpenHexagon/Core/HexagonGame.cpp | 25 |
7 files changed, 192 insertions, 11 deletions
diff --git a/_RELEASE/Assets/assets.json b/_RELEASE/Assets/assets.json index 9a95ad1d..dd7fedcf 100644 --- a/_RELEASE/Assets/assets.json +++ b/_RELEASE/Assets/assets.json @@ -40,6 +40,7 @@ "personalBest.ogg", "restart.ogg", "select.ogg", - "swap.ogg" + "swap.ogg", + "swapBlip.ogg" ] } diff --git a/include/SSVOpenHexagon/Components/CPlayer.hpp b/include/SSVOpenHexagon/Components/CPlayer.hpp index 4e008e06..834d6db5 100644 --- a/include/SSVOpenHexagon/Components/CPlayer.hpp +++ b/include/SSVOpenHexagon/Components/CPlayer.hpp @@ -114,6 +114,8 @@ public: void updatePosition(const float radius); + [[nodiscard]] sf::Color getColor(const sf::Color& colorPlayer) const; + [[nodiscard]] sf::Color getColorAdjustedForSwap( const sf::Color& colorPlayer) const; @@ -121,7 +123,7 @@ public: const sf::Color& colorPlayer, Utils::FastVertexVectorQuads& wallQuads, Utils::FastVertexVectorTris& capTris, Utils::FastVertexVectorTris& playerTris, const sf::Color& capColor, - const float angleTiltIntensity); + const float angleTiltIntensity, const bool swapBlinkingEffect); [[nodiscard]] bool push(const int movementDir, const float radius, const CWall& wall, const sf::Vector2f& mCenterPos, diff --git a/include/SSVOpenHexagon/Core/HexagonGame.hpp b/include/SSVOpenHexagon/Core/HexagonGame.hpp index 265acfb4..9123e98e 100644 --- a/include/SSVOpenHexagon/Core/HexagonGame.hpp +++ b/include/SSVOpenHexagon/Core/HexagonGame.hpp @@ -180,12 +180,28 @@ private: float angle; }; + struct SwapParticle + { + sf::Sprite sprite; + sf::Vector2f velocity; + }; + sf::Texture* txStarParticle; sf::Texture* txSmallCircle; std::vector<Particle> particles; std::vector<TrailParticle> trailParticles; + std::vector<SwapParticle> swapParticles; bool mustSpawnPBParticles{false}; + + struct SwapParticleSpawnInfo + { + bool ready; + sf::Vector2f position; + float angle; + }; + + std::optional<SwapParticleSpawnInfo> swapParticlesSpawnInfo; float nextPBParticleSpawn{0.f}; float pbTextGrowth{0.f}; @@ -238,6 +254,8 @@ private: int inputMovement{0}; bool inputImplCW{false}; bool inputImplCCW{false}; + bool playerNowReadyToSwap{false}; + std::ostringstream os; sf::Text fpsText; @@ -344,6 +362,7 @@ private: void updateLevelInfo(); void updateParticles(ssvu::FT mFT); void updateTrailParticles(ssvu::FT mFT); + void updateSwapParticles(ssvu::FT mFT); // Post update methods void postUpdate(); @@ -365,6 +384,7 @@ private: void drawLevelInfo(); void drawParticles(); void drawTrailParticles(); + void drawSwapParticles(); void drawImguiLuaConsole(); // Data-related methods @@ -502,6 +522,8 @@ public: [[nodiscard]] HGAssets& getAssets(); [[nodiscard]] sf::Color getColorMain() const; [[nodiscard]] sf::Color getColorPlayer() const; + [[nodiscard]] sf::Color getColorPlayerAdjustedForSwap() const; + [[nodiscard]] sf::Color getColorPlayerTrail() const; [[nodiscard]] sf::Color getColorText() const; [[nodiscard]] sf::Color getColorCap() const; [[nodiscard]] sf::Color getColorWall() const; diff --git a/src/SSVOpenHexagon/Components/CPlayer.cpp b/src/SSVOpenHexagon/Components/CPlayer.cpp index dc112760..b452d940 100644 --- a/src/SSVOpenHexagon/Components/CPlayer.cpp +++ b/src/SSVOpenHexagon/Components/CPlayer.cpp @@ -59,6 +59,12 @@ CPlayer::CPlayer(const sf::Vector2f& pos, const float swapCooldown, _currTiltedAngle{0} {} +[[nodiscard]] sf::Color CPlayer::getColor(const sf::Color& colorPlayer) const +{ + return !_deadEffectTimer.isRunning() ? colorPlayer + : Utils::getColorFromHue(_hue / 360.f); +} + [[nodiscard]] sf::Color CPlayer::getColorAdjustedForSwap( const sf::Color& colorPlayer) const { @@ -68,15 +74,14 @@ CPlayer::CPlayer(const sf::Vector2f& pos, const float swapCooldown, std::fmod(_swapBlinkTimer.getCurrent() / 12.f, 0.2f)); } - return !_deadEffectTimer.isRunning() ? colorPlayer - : Utils::getColorFromHue(_hue / 360.f); + return getColor(colorPlayer); } void CPlayer::draw(const unsigned int sides, const sf::Color& colorMain, const sf::Color& colorPlayer, Utils::FastVertexVectorQuads& wallQuads, Utils::FastVertexVectorTris& capTris, Utils::FastVertexVectorTris& playerTris, const sf::Color& capColor, - const float angleTiltIntensity) + const float angleTiltIntensity, const bool swapBlinkingEffect) { drawPivot(sides, colorMain, wallQuads, capTris, capColor); @@ -95,7 +100,9 @@ void CPlayer::draw(const unsigned int sides, const sf::Color& colorMain, _pos, tiltedAngle + ssvu::toRad(100.f), _size + _triangleWidth); playerTris.reserve_more(3); - playerTris.batch_unsafe_emplace_back(getColorAdjustedForSwap(colorPlayer), + playerTris.batch_unsafe_emplace_back( + swapBlinkingEffect ? getColorAdjustedForSwap(colorPlayer) + : getColor(colorPlayer), ssvs::getOrbitRad(_pos, tiltedAngle, _size), pLeft, pRight); } diff --git a/src/SSVOpenHexagon/Core/HGGraphics.cpp b/src/SSVOpenHexagon/Core/HGGraphics.cpp index 54bd211e..c53f14b7 100644 --- a/src/SSVOpenHexagon/Core/HGGraphics.cpp +++ b/src/SSVOpenHexagon/Core/HGGraphics.cpp @@ -116,8 +116,8 @@ void HexagonGame::draw() if(status.started) { player.draw(getSides(), getColorMain(), getColorPlayer(), pivotQuads, - capTris, playerTris, getColorCap(), - Config::getAngleTiltIntensity()); + capTris, playerTris, getColorCap(), Config::getAngleTiltIntensity(), + Config::getShowSwapBlinkingEffect()); } if(Config::get3D()) @@ -237,6 +237,11 @@ void HexagonGame::draw() drawTrailParticles(); } + if(Config::getShowSwapParticles()) + { + drawSwapParticles(); + } + render(wallQuads); render(capTris); render(pivotQuads); @@ -373,6 +378,14 @@ void HexagonGame::drawTrailParticles() } } +void HexagonGame::drawSwapParticles() +{ + for(SwapParticle& p : swapParticles) + { + render(p.sprite); + } +} + void HexagonGame::updateText(ssvu::FT mFT) { if(window == nullptr) diff --git a/src/SSVOpenHexagon/Core/HGUpdate.cpp b/src/SSVOpenHexagon/Core/HGUpdate.cpp index 66789404..703e812f 100644 --- a/src/SSVOpenHexagon/Core/HGUpdate.cpp +++ b/src/SSVOpenHexagon/Core/HGUpdate.cpp @@ -24,6 +24,7 @@ #include "SSVOpenHexagon/Core/Joystick.hpp" #include "SSVOpenHexagon/Core/LuaScripting.hpp" #include "SSVOpenHexagon/Core/Steam.hpp" +#include "SSVUtils/Core/Utils/Rnd.hpp" #ifndef SSVOH_ANDROID #include <imgui.h> @@ -243,12 +244,35 @@ void HexagonGame::update(ssvu::FT mFT, const float timescale) player.updateInputMovement(getInputMovement(), getPlayerSpeedMult(), getInputFocused(), mFT); + // Play "swap ready blip" sound and create particles + if(!playerNowReadyToSwap && player.isReadyToSwap()) + { + playerNowReadyToSwap = true; + + if(Config::getPlaySwapReadySound()) + { + playSoundOverride("swapBlip.ogg"); + } + + swapParticlesSpawnInfo = + SwapParticleSpawnInfo{.ready{true}, + .position{player.getPosition()}, + .angle{player.getPlayerAngle()}}; + } + + // Create particles after swap if(getLevelStatus().swapEnabled && getInputSwap() && player.isReadyToSwap()) { + swapParticlesSpawnInfo = + SwapParticleSpawnInfo{.ready{false}, + .position{player.getPosition()}, + .angle{player.getPlayerAngle()}}; + performPlayerSwap(true /* mPlaySound */); player.resetSwap(getSwapCooldown()); player.setJustSwapped(true); + playerNowReadyToSwap = false; } else { @@ -344,6 +368,11 @@ void HexagonGame::update(ssvu::FT mFT, const float timescale) updateTrailParticles(mFT); } + if(Config::getShowSwapParticles()) + { + updateSwapParticles(mFT); + } + overlayCamera->update(mFT); backgroundCamera->update(mFT); } @@ -944,9 +973,7 @@ void HexagonGame::updateTrailParticles(ssvu::FT mFT) const float scale = Config::getPlayerTrailScale(); p.sprite.setScale({scale, scale}); - sf::Color c = Config::getPlayerTrailHasSwapColor() - ? player.getColorAdjustedForSwap(getColorPlayer()) - : getColorPlayer(); + sf::Color c = getColorPlayerTrail(); c.a = Config::getPlayerTrailAlpha(); p.sprite.setColor(c); @@ -980,6 +1007,90 @@ void HexagonGame::updateTrailParticles(ssvu::FT mFT) } } +void HexagonGame::updateSwapParticles(ssvu::FT mFT) +{ + SSVOH_ASSERT(window != nullptr); + + const auto isDead = [&](const SwapParticle& p) + { return p.sprite.getColor().a <= 3; }; + + const auto makeSwapParticle = [this](const SwapParticleSpawnInfo& si, + const float expand, const float speedMult, + const float scaleMult, const float alpha) + { + SwapParticle p; + + SSVOH_ASSERT(txSmallCircle != nullptr); + p.sprite.setTexture(*txSmallCircle); + p.sprite.setPosition(si.position); + p.sprite.setOrigin(sf::Vector2f{txSmallCircle->getSize()} / 2.f); + + const float scale = ssvu::getRndR(0.65f, 1.35f) * scaleMult; + p.sprite.setScale({scale, scale}); + + sf::Color c = getColorPlayerTrail(); + + c.a = alpha; + p.sprite.setColor(c); + + p.velocity = + ssvs::getVecFromRad(si.angle + ssvu::getRndR(-expand, expand), + ssvu::getRndR(0.1f, 10.f) * speedMult); + + return p; + }; + + ssvu::eraseRemoveIf(swapParticles, isDead); + + for(SwapParticle& p : swapParticles) + { + sf::Color color = p.sprite.getColor(); + + const float newAlpha = + Utils::getMoveTowardsZero(static_cast<float>(color.a), 3.5f * mFT); + + color.a = static_cast<sf::Uint8>(newAlpha); + p.sprite.setColor(color); + + p.sprite.setScale(p.sprite.getScale() * 0.98f); + p.sprite.setPosition(p.sprite.getPosition() + p.velocity * mFT); + } + + if(swapParticlesSpawnInfo.has_value()) + { + if(swapParticlesSpawnInfo->ready == false) + { + for(int i = 0; i < 20; ++i) + { + swapParticles.emplace_back( + makeSwapParticle(*swapParticlesSpawnInfo, + 0.45f /* expand */, 1.f /* speedMult */, + 1.f /* scaleMult */, 45.f /* alpha */)); + } + + for(int i = 0; i < 10; ++i) + { + swapParticles.emplace_back( + makeSwapParticle(*swapParticlesSpawnInfo, + 3.14f /* expand */, 0.45f /* speedMult */, + 0.75f /* scaleMult */, 35.f /* alpha */)); + } + } + else + { + for(int i = 0; i < 14; ++i) + { + swapParticles.emplace_back( + makeSwapParticle(*swapParticlesSpawnInfo, + 3.14f /* expand */, 1.3f /* speedMult */, + 0.4f /* scaleMult */, 140.f /* alpha */)); + } + } + + swapParticlesSpawnInfo.reset(); + } +} + #ifndef SSVOH_ANDROID static int ilcTextEditCallbackStub(ImGuiInputTextCallbackData* data) { diff --git a/src/SSVOpenHexagon/Core/HexagonGame.cpp b/src/SSVOpenHexagon/Core/HexagonGame.cpp index eb621791..37aacf03 100644 --- a/src/SSVOpenHexagon/Core/HexagonGame.cpp +++ b/src/SSVOpenHexagon/Core/HexagonGame.cpp @@ -666,9 +666,11 @@ void HexagonGame::newGame(const std::string& mPackId, const std::string& mId, // Particles cleanup pbTextGrowth = 0.f; mustSpawnPBParticles = false; + swapParticlesSpawnInfo.reset(); nextPBParticleSpawn = 0.f; particles.clear(); trailParticles.clear(); + swapParticles.clear(); // Re-init default flash effect initFlashEffect(255, 255, 255); @@ -694,6 +696,7 @@ void HexagonGame::newGame(const std::string& mPackId, const std::string& mId, // Lua context and game status cleanup inputImplCCW = inputImplCW = false; + playerNowReadyToSwap = false; lua = Lua::LuaContext{}; calledDeprecatedFunctions.clear(); @@ -1397,6 +1400,28 @@ auto HexagonGame::getColorPlayer() const -> sf::Color return styleData.getPlayerColor(); } +auto HexagonGame::getColorPlayerAdjustedForSwap() const -> sf::Color +{ + if(Config::getBlackAndWhite()) + { + return sf::Color(255, 255, 255, styleData.getPlayerColor().a); + } + + if(!Config::getShowSwapBlinkingEffect()) + { + return getColorPlayer(); + } + + return player.getColorAdjustedForSwap(getColorPlayer()); +} + +auto HexagonGame::getColorPlayerTrail() const -> sf::Color +{ + return Config::getPlayerTrailHasSwapColor() + ? getColorPlayerAdjustedForSwap() + : getColorPlayer(); +} + auto HexagonGame::getColorText() const -> sf::Color { if(Config::getBlackAndWhite()) |