diff options
author | Vittorio Romeo <vittorio.romeo@outlook.com> | 2021-03-01 18:21:39 +0000 |
---|---|---|
committer | Vittorio Romeo <vittorio.romeo@outlook.com> | 2021-03-01 18:21:39 +0000 |
commit | 191560755ad7b1d0d9f1d7d825221d6274a8be49 (patch) | |
tree | cc246598815dba6ec631a4c55724a838b7d2b5a5 | |
parent | 5248d3546eb363fc6de0808d54efd470625d0227 (diff) |
Add basic particle system and success particlesimprove_tutorial
-rw-r--r-- | _RELEASE/Assets/assets.json | 3 | ||||
-rw-r--r-- | _RELEASE/Assets/starParticle.png | bin | 0 -> 2105 bytes | |||
-rw-r--r-- | _RELEASE/Packs/hypercube/Scripts/commonpatterns.lua | 8 | ||||
-rw-r--r-- | _RELEASE/Packs/workshopexample/Scripts/commonpatterns.lua | 82 | ||||
-rw-r--r-- | _RELEASE/Temp/example/Scripts/commonpatterns.lua | 82 | ||||
-rw-r--r-- | include/SSVOpenHexagon/Core/HexagonGame.hpp | 25 | ||||
-rw-r--r-- | src/SSVOpenHexagon/Core/HGGraphics.cpp | 55 | ||||
-rw-r--r-- | src/SSVOpenHexagon/Core/HGUpdate.cpp | 62 | ||||
-rw-r--r-- | src/SSVOpenHexagon/Core/HexagonGame.cpp | 29 | ||||
-rw-r--r-- | src/SSVOpenHexagon/Core/MenuGame.cpp | 13 |
10 files changed, 252 insertions, 107 deletions
diff --git a/_RELEASE/Assets/assets.json b/_RELEASE/Assets/assets.json index 17c254da..f7a28889 100644 --- a/_RELEASE/Assets/assets.json +++ b/_RELEASE/Assets/assets.json @@ -16,7 +16,8 @@ "keyArrow.png", "keyFocus.png", "keySwap.png", - "replayIcon.png" + "replayIcon.png", + "starParticle.png" ], "soundBuffers": [ diff --git a/_RELEASE/Assets/starParticle.png b/_RELEASE/Assets/starParticle.png Binary files differnew file mode 100644 index 00000000..8af2fb7a --- /dev/null +++ b/_RELEASE/Assets/starParticle.png diff --git a/_RELEASE/Packs/hypercube/Scripts/commonpatterns.lua b/_RELEASE/Packs/hypercube/Scripts/commonpatterns.lua index 4d503483..6f8b3df7 100644 --- a/_RELEASE/Packs/hypercube/Scripts/commonpatterns.lua +++ b/_RELEASE/Packs/hypercube/Scripts/commonpatterns.lua @@ -15,8 +15,8 @@ end -- pSpiral: spawns a spiral of cWallEx function pSpiral(mTimes, mExtra) local oldThickness = THICKNESS - THICKNESS = getPerfectThickness(THICKNESS) - local delay = getPerfectDelay(THICKNESS) + THICKNESS = getPerfectThickness(THICKNESS) * l_getDelayMult() + local delay = getPerfectDelay(THICKNESS) / l_getDelayMult() local startSide = getRandomSide() local loopDir = getRandomDir() local j = 0 @@ -35,8 +35,8 @@ end -- pMirrorSpiral: spawns a spiral of rWallEx function pMirrorSpiral(mTimes, mExtra) local oldThickness = THICKNESS - THICKNESS = getPerfectThickness(THICKNESS) - local delay = getPerfectDelay(THICKNESS) + THICKNESS = getPerfectThickness(THICKNESS) * l_getDelayMult() + local delay = getPerfectDelay(THICKNESS) / l_getDelayMult() local startSide = getRandomSide() local loopDir = getRandomDir() j = 0 diff --git a/_RELEASE/Packs/workshopexample/Scripts/commonpatterns.lua b/_RELEASE/Packs/workshopexample/Scripts/commonpatterns.lua index 29129c8f..71567ae2 100644 --- a/_RELEASE/Packs/workshopexample/Scripts/commonpatterns.lua +++ b/_RELEASE/Packs/workshopexample/Scripts/commonpatterns.lua @@ -3,32 +3,32 @@ u_execScript("common.lua") -- pAltBarrage: spawns a series of cAltBarrage function pAltBarrage(mTimes, mStep) delay = getPerfectDelayDM(THICKNESS) * 5.6 - + for i = 0, mTimes do cAltBarrage(i, mStep) t_wait(delay) end - + t_wait(delay) end -- pSpiral: spawns a spiral of cWall function pSpiral(mTimes, mExtra) oldThickness = THICKNESS - THICKNESS = getPerfectThickness(THICKNESS) - delay = getPerfectDelay(THICKNESS) + THICKNESS = getPerfectThickness(THICKNESS) * l_getDelayMult() + delay = getPerfectDelay(THICKNESS) / l_getDelayMult() startSide = getRandomSide() - loopDir = getRandomDir() + loopDir = getRandomDir() j = 0 - + for i = 0, mTimes do cWall(startSide + j, mExtra) j = j + loopDir t_wait(delay) end - + THICKNESS = oldThickness - + t_wait(getPerfectDelayDM(THICKNESS) * 6.5) end @@ -38,17 +38,17 @@ function pMirrorSpiral(mTimes, mExtra) THICKNESS = getPerfectThickness(THICKNESS) delay = getPerfectDelay(THICKNESS) startSide = getRandomSide() - loopDir = getRandomDir() + loopDir = getRandomDir() j = 0 - + for i = 0, mTimes do rWallEx(startSide + j, mExtra) j = j + loopDir t_wait(delay) end - + THICKNESS = oldThickness - + t_wait(getPerfectDelayDM(THICKNESS) * 6.5) end @@ -58,24 +58,24 @@ function pMirrorSpiralDouble(mTimes, mExtra) THICKNESS = getPerfectThickness(THICKNESS) delay = getPerfectDelayDM(THICKNESS) startSide = getRandomSide() - loopDir = getRandomDir() + loopDir = getRandomDir() j = 0 - + for i = 0, mTimes do rWallEx(startSide + j, mExtra) j = j + loopDir t_wait(delay) end - + rWallEx(startSide + j, mExtra) t_wait(delay * 0.9) - + for i = 0, mTimes + 1 do rWallEx(startSide + j, mExtra) j = j - loopDir t_wait(delay) end - + THICKNESS = oldThickness t_wait(getPerfectDelayDM(THICKNESS) * 7.5) end @@ -84,16 +84,16 @@ end function pBarrageSpiral(mTimes, mDelayMult, mStep) delay = getPerfectDelayDM(THICKNESS) * 5.6 * mDelayMult startSide = getRandomSide() - loopDir = mStep * getRandomDir() + loopDir = mStep * getRandomDir() j = 0 - + for i = 0, mTimes do cBarrage(startSide + j) j = j + loopDir t_wait(delay) if(l_getSides() < 6) then t_wait(delay * 0.6) end end - + t_wait(getPerfectDelayDM(THICKNESS) * 6.1) end @@ -101,42 +101,42 @@ end function pDMBarrageSpiral(mTimes, mDelayMult, mStep) delay = (getPerfectDelayDM(THICKNESS) * 5.42) * (mDelayMult / (u_getDifficultyMult() ^ 0.4)) * (u_getSpeedMultDM() ^ 0.35) startSide = getRandomSide() - loopDir = mStep * getRandomDir() + loopDir = mStep * getRandomDir() j = 0 - + for i = 0, mTimes do cBarrage(startSide + j) j = j + loopDir t_wait(delay) if(l_getSides() < 6) then t_wait(delay * 0.49) end end - + t_wait(getPerfectDelayDM(THICKNESS) * (6.7 * (u_getDifficultyMult() ^ 0.7))) end -- pWallExVortex: spawns left-left right-right spiral patters function pWallExVortex(mTimes, mStep, mExtraMult) - delay = getPerfectDelayDM(THICKNESS) * 5.0 + delay = getPerfectDelayDM(THICKNESS) * 5.0 startSide = getRandomSide() loopDir = getRandomDir() currentSide = startSide - + for j = 0, mTimes do for i = 0, mStep do currentSide = currentSide + loopDir rWallEx(currentSide, loopDir * mExtraMult) t_wait(delay) end - + loopDir = loopDir * -1 - + for i = 0, mStep + 1 do currentSide = currentSide + loopDir; rWallEx(currentSide, loopDir * mExtraMult) t_wait(delay) end end - + t_wait(getPerfectDelayDM(THICKNESS) * 5.5) end @@ -144,7 +144,7 @@ end function pInverseBarrage(mTimes) delay = getPerfectDelayDM(THICKNESS) * 9.9 startSide = getRandomSide() - + for i = 0, mTimes do cBarrage(startSide) t_wait(delay) @@ -152,7 +152,7 @@ function pInverseBarrage(mTimes) cBarrage(startSide + getHalfSides()) t_wait(delay) end - + t_wait(getPerfectDelayDM(THICKNESS) * 2.5) end @@ -160,14 +160,14 @@ end function pRandomBarrage(mTimes, mDelayMult) side = getRandomSide() oldSide = 0 - - for i = 0, mTimes do + + for i = 0, mTimes do cBarrage(side) oldSide = side side = getRandomSide() t_wait(getPerfectDelayDM(THICKNESS) * (2 + (getSideDistance(side, oldSide)*mDelayMult))) end - + t_wait(getPerfectDelayDM(THICKNESS) * 5.6) end @@ -175,12 +175,12 @@ end function pMirrorWallStrip(mTimes, mExtra) delay = getPerfectDelayDM(THICKNESS) * 3.65 startSide = getRandomSide() - + for i = 0, mTimes do rWallEx(startSide, mExtra) t_wait(delay) end - + t_wait(getPerfectDelayDM(THICKNESS) * 5.00) end @@ -191,19 +191,19 @@ function pTunnel(mTimes) delay = getPerfectDelay(myThickness) * 5 startSide = getRandomSide() loopDir = getRandomDir() - + THICKNESS = myThickness - + for i = 0, mTimes do if i < mTimes then w_wall(startSide, myThickness + 5 * u_getSpeedMultDM() * delay) end - + cBarrage(startSide + loopDir) t_wait(delay) - + loopDir = loopDir * -1 end - + THICKNESS = oldThickness -end
\ No newline at end of file +end diff --git a/_RELEASE/Temp/example/Scripts/commonpatterns.lua b/_RELEASE/Temp/example/Scripts/commonpatterns.lua index 29129c8f..71567ae2 100644 --- a/_RELEASE/Temp/example/Scripts/commonpatterns.lua +++ b/_RELEASE/Temp/example/Scripts/commonpatterns.lua @@ -3,32 +3,32 @@ u_execScript("common.lua") -- pAltBarrage: spawns a series of cAltBarrage function pAltBarrage(mTimes, mStep) delay = getPerfectDelayDM(THICKNESS) * 5.6 - + for i = 0, mTimes do cAltBarrage(i, mStep) t_wait(delay) end - + t_wait(delay) end -- pSpiral: spawns a spiral of cWall function pSpiral(mTimes, mExtra) oldThickness = THICKNESS - THICKNESS = getPerfectThickness(THICKNESS) - delay = getPerfectDelay(THICKNESS) + THICKNESS = getPerfectThickness(THICKNESS) * l_getDelayMult() + delay = getPerfectDelay(THICKNESS) / l_getDelayMult() startSide = getRandomSide() - loopDir = getRandomDir() + loopDir = getRandomDir() j = 0 - + for i = 0, mTimes do cWall(startSide + j, mExtra) j = j + loopDir t_wait(delay) end - + THICKNESS = oldThickness - + t_wait(getPerfectDelayDM(THICKNESS) * 6.5) end @@ -38,17 +38,17 @@ function pMirrorSpiral(mTimes, mExtra) THICKNESS = getPerfectThickness(THICKNESS) delay = getPerfectDelay(THICKNESS) startSide = getRandomSide() - loopDir = getRandomDir() + loopDir = getRandomDir() j = 0 - + for i = 0, mTimes do rWallEx(startSide + j, mExtra) j = j + loopDir t_wait(delay) end - + THICKNESS = oldThickness - + t_wait(getPerfectDelayDM(THICKNESS) * 6.5) end @@ -58,24 +58,24 @@ function pMirrorSpiralDouble(mTimes, mExtra) THICKNESS = getPerfectThickness(THICKNESS) delay = getPerfectDelayDM(THICKNESS) startSide = getRandomSide() - loopDir = getRandomDir() + loopDir = getRandomDir() j = 0 - + for i = 0, mTimes do rWallEx(startSide + j, mExtra) j = j + loopDir t_wait(delay) end - + rWallEx(startSide + j, mExtra) t_wait(delay * 0.9) - + for i = 0, mTimes + 1 do rWallEx(startSide + j, mExtra) j = j - loopDir t_wait(delay) end - + THICKNESS = oldThickness t_wait(getPerfectDelayDM(THICKNESS) * 7.5) end @@ -84,16 +84,16 @@ end function pBarrageSpiral(mTimes, mDelayMult, mStep) delay = getPerfectDelayDM(THICKNESS) * 5.6 * mDelayMult startSide = getRandomSide() - loopDir = mStep * getRandomDir() + loopDir = mStep * getRandomDir() j = 0 - + for i = 0, mTimes do cBarrage(startSide + j) j = j + loopDir t_wait(delay) if(l_getSides() < 6) then t_wait(delay * 0.6) end end - + t_wait(getPerfectDelayDM(THICKNESS) * 6.1) end @@ -101,42 +101,42 @@ end function pDMBarrageSpiral(mTimes, mDelayMult, mStep) delay = (getPerfectDelayDM(THICKNESS) * 5.42) * (mDelayMult / (u_getDifficultyMult() ^ 0.4)) * (u_getSpeedMultDM() ^ 0.35) startSide = getRandomSide() - loopDir = mStep * getRandomDir() + loopDir = mStep * getRandomDir() j = 0 - + for i = 0, mTimes do cBarrage(startSide + j) j = j + loopDir t_wait(delay) if(l_getSides() < 6) then t_wait(delay * 0.49) end end - + t_wait(getPerfectDelayDM(THICKNESS) * (6.7 * (u_getDifficultyMult() ^ 0.7))) end -- pWallExVortex: spawns left-left right-right spiral patters function pWallExVortex(mTimes, mStep, mExtraMult) - delay = getPerfectDelayDM(THICKNESS) * 5.0 + delay = getPerfectDelayDM(THICKNESS) * 5.0 startSide = getRandomSide() loopDir = getRandomDir() currentSide = startSide - + for j = 0, mTimes do for i = 0, mStep do currentSide = currentSide + loopDir rWallEx(currentSide, loopDir * mExtraMult) t_wait(delay) end - + loopDir = loopDir * -1 - + for i = 0, mStep + 1 do currentSide = currentSide + loopDir; rWallEx(currentSide, loopDir * mExtraMult) t_wait(delay) end end - + t_wait(getPerfectDelayDM(THICKNESS) * 5.5) end @@ -144,7 +144,7 @@ end function pInverseBarrage(mTimes) delay = getPerfectDelayDM(THICKNESS) * 9.9 startSide = getRandomSide() - + for i = 0, mTimes do cBarrage(startSide) t_wait(delay) @@ -152,7 +152,7 @@ function pInverseBarrage(mTimes) cBarrage(startSide + getHalfSides()) t_wait(delay) end - + t_wait(getPerfectDelayDM(THICKNESS) * 2.5) end @@ -160,14 +160,14 @@ end function pRandomBarrage(mTimes, mDelayMult) side = getRandomSide() oldSide = 0 - - for i = 0, mTimes do + + for i = 0, mTimes do cBarrage(side) oldSide = side side = getRandomSide() t_wait(getPerfectDelayDM(THICKNESS) * (2 + (getSideDistance(side, oldSide)*mDelayMult))) end - + t_wait(getPerfectDelayDM(THICKNESS) * 5.6) end @@ -175,12 +175,12 @@ end function pMirrorWallStrip(mTimes, mExtra) delay = getPerfectDelayDM(THICKNESS) * 3.65 startSide = getRandomSide() - + for i = 0, mTimes do rWallEx(startSide, mExtra) t_wait(delay) end - + t_wait(getPerfectDelayDM(THICKNESS) * 5.00) end @@ -191,19 +191,19 @@ function pTunnel(mTimes) delay = getPerfectDelay(myThickness) * 5 startSide = getRandomSide() loopDir = getRandomDir() - + THICKNESS = myThickness - + for i = 0, mTimes do if i < mTimes then w_wall(startSide, myThickness + 5 * u_getSpeedMultDM() * delay) end - + cBarrage(startSide + loopDir) t_wait(delay) - + loopDir = loopDir * -1 end - + THICKNESS = oldThickness -end
\ No newline at end of file +end diff --git a/include/SSVOpenHexagon/Core/HexagonGame.hpp b/include/SSVOpenHexagon/Core/HexagonGame.hpp index f3a0a0cc..f9c01d61 100644 --- a/include/SSVOpenHexagon/Core/HexagonGame.hpp +++ b/include/SSVOpenHexagon/Core/HexagonGame.hpp @@ -105,8 +105,23 @@ private: sf::Text messageText{"", assets.get<sf::Font>("forcedsquare.ttf"), ssvu::toNum<unsigned int>(38.f / Config::getZoomFactor())}; + sf::Text pbText{"", assets.get<sf::Font>("forcedsquare.ttf"), + ssvu::toNum<unsigned int>(65.f / Config::getZoomFactor())}; + ssvs::VertexVector<sf::PrimitiveType::Quads> flashPolygon{4}; + struct Particle + { + sf::Sprite sprite; + sf::Vector2f velocity; + float angularVelocity; + }; + + std::vector<Particle> particles; + bool mustSpawnPBParticles{false}; + float nextPBParticleSpawn{0.f}; + float pbTextGrowth{0.f}; + sf::Sprite keyIconLeft; sf::Sprite keyIconRight; sf::Sprite keyIconFocus; @@ -278,8 +293,9 @@ private: void updateRotation(ssvu::FT mFT); void updateFlash(ssvu::FT mFT); void update3D(ssvu::FT mFT); - void updateText(); + void updateText(ssvu::FT mFT); void updateKeyIcons(); + void updateParticles(ssvu::FT mFT); // Draw methods void draw(); @@ -291,8 +307,10 @@ private: // Draw methods void drawText_TimeAndStatus(const sf::Color& offsetColor); void drawText_Message(const sf::Color& offsetColor); + void drawText_PersonalBest(const sf::Color& offsetColor); void drawText(); void drawKeyIcons(); + void drawParticles(); // Data-related methods void setLevelData(const LevelData& mLevelData, bool mMusicFirstPlay); @@ -393,9 +411,10 @@ public: void updateRichPresenceCallbacks(); // Graphics-related methods - void render(sf::Drawable& mDrawable) + void render(sf::Drawable& mDrawable, + const sf::RenderStates& mStates = sf::RenderStates::Default) { - window.draw(mDrawable); + window.draw(mDrawable, mStates); } // Setters diff --git a/src/SSVOpenHexagon/Core/HGGraphics.cpp b/src/SSVOpenHexagon/Core/HGGraphics.cpp index 12bbfa9d..a8fe04b7 100644 --- a/src/SSVOpenHexagon/Core/HGGraphics.cpp +++ b/src/SSVOpenHexagon/Core/HGGraphics.cpp @@ -153,6 +153,8 @@ void HexagonGame::draw() render(capTris); overlayCamera.apply(); + + drawParticles(); drawText(); if(Config::getShowKeyIcons() || mustShowReplayUI()) @@ -215,8 +217,18 @@ void HexagonGame::drawKeyIcons() } } -void HexagonGame::updateText() +void HexagonGame::drawParticles() { + for(Particle& p : particles) + { + render(p.sprite); + } +} + +void HexagonGame::updateText(ssvu::FT mFT) +{ + pbTextGrowth += 0.08f * mFT; + os.str(""); if(levelStatus.tutorialMode) @@ -343,6 +355,10 @@ void HexagonGame::updateText() messageText.setCharacterSize(getScaledCharacterSize(38.f)); messageText.setOrigin(getGlobalWidth(messageText) / 2.f, 0); + const float growth = std::sin(pbTextGrowth); + pbText.setCharacterSize(getScaledCharacterSize(64.f) + growth * 10.f); + pbText.setOrigin(getGlobalWidth(pbText) / 2.f, 0); + // ------------------------------------------------------------------------ if(mustShowReplayUI()) { @@ -435,29 +451,47 @@ void HexagonGame::drawText_TimeAndStatus(const sf::Color& offsetColor) } } -void HexagonGame::drawText_Message(const sf::Color& offsetColor) +template <typename FRender> +static void drawTextMessagePBImpl(sf::Text& text, const sf::Color& offsetColor, + const sf::Vector2f& pos, const sf::Color& color, float outlineThickness, + FRender&& fRender) { - if(messageText.getString() == "") + if(text.getString().isEmpty()) { return; } if(Config::getDrawTextOutlines()) { - messageText.setOutlineColor(offsetColor); - messageText.setOutlineThickness(1.f); + text.setOutlineColor(offsetColor); + text.setOutlineThickness(outlineThickness); } else { - messageText.setOutlineThickness(0.f); + text.setOutlineThickness(0.f); } - messageText.setPosition( - sf::Vector2f{Config::getWidth() / 2.f, Config::getHeight() / 6.f}); - messageText.setFillColor(getColorText()); - render(messageText); + text.setPosition(pos); + text.setFillColor(color); + + fRender(text); } +void HexagonGame::drawText_Message(const sf::Color& offsetColor) +{ + drawTextMessagePBImpl(messageText, offsetColor, + {Config::getWidth() / 2.f, Config::getHeight() / 6.f}, getColorText(), + 1.f /* outlineThickness */, [this](sf::Text& t) { render(t); }); +} + +void HexagonGame::drawText_PersonalBest(const sf::Color& offsetColor) +{ + drawTextMessagePBImpl(pbText, offsetColor, + {Config::getWidth() / 2.f, + Config::getHeight() - Config::getHeight() / 4.f}, + getColorText(), 4.f /* outlineThickness */, + [this](sf::Text& t) { render(t); }); +} void HexagonGame::drawText() { @@ -466,6 +500,7 @@ void HexagonGame::drawText() drawText_TimeAndStatus(offsetColor); drawText_Message(offsetColor); + drawText_PersonalBest(offsetColor); } } // namespace hg diff --git a/src/SSVOpenHexagon/Core/HGUpdate.cpp b/src/SSVOpenHexagon/Core/HGUpdate.cpp index 296768c6..c116e90c 100644 --- a/src/SSVOpenHexagon/Core/HGUpdate.cpp +++ b/src/SSVOpenHexagon/Core/HGUpdate.cpp @@ -9,6 +9,7 @@ #include <SSVStart/Utils/Vector2.hpp> #include <SSVUtils/Core/Common/Frametime.hpp> +#include <SSVUtils/Core/Utils/Containers.hpp> using namespace std; using namespace sf; @@ -39,7 +40,7 @@ void HexagonGame::update(ssvu::FT mFT) } updateRichPresenceCallbacks(); - updateText(); + updateText(mFT); updateFlash(mFT); effectTimelineManager.update(mFT); @@ -150,6 +151,8 @@ void HexagonGame::update(ssvu::FT mFT) } } + updateParticles(mFT); + overlayCamera.update(mFT); backgroundCamera.update(mFT); @@ -509,6 +512,7 @@ void HexagonGame::updateLevel(ssvu::FT mFT) timelineRunner = {}; } } + void HexagonGame::updatePulse(ssvu::FT mFT) { if(status.pulseDelay <= 0 && status.pulseDelayHalf <= 0) @@ -542,6 +546,7 @@ void HexagonGame::updatePulse(ssvu::FT mFT) (Config::getHeight() * Config::getZoomFactor()) * p}}); backgroundCamera.setRotation(rotation); } + void HexagonGame::updateBeatPulse(ssvu::FT mFT) { if(status.beatPulseDelay <= 0) @@ -564,6 +569,7 @@ void HexagonGame::updateBeatPulse(ssvu::FT mFT) status.radius = radiusMin * (status.pulse / levelStatus.pulseMin) + status.beatPulse; } + void HexagonGame::updateRotation(ssvu::FT mFT) { auto nextRotation(getRotationSpeed() * 10.f); @@ -579,6 +585,7 @@ void HexagonGame::updateRotation(ssvu::FT mFT) backgroundCamera.turn(nextRotation); } + void HexagonGame::updateFlash(ssvu::FT mFT) { if(status.flashEffect > 0) @@ -591,6 +598,7 @@ void HexagonGame::updateFlash(ssvu::FT mFT) flashPolygon[i].color.a = status.flashEffect; } } + void HexagonGame::update3D(ssvu::FT mFT) { status.pulse3D += styleData._3dPulseSpeed * status.pulse3DDirection * mFT; @@ -604,4 +612,56 @@ void HexagonGame::update3D(ssvu::FT mFT) } } +void HexagonGame::updateParticles(ssvu::FT mFT) +{ + const auto isOutOfBounds = [](const Particle& p) { + const sf::Sprite& sp = p.sprite; + const sf::Vector2f& pos = sp.getPosition(); + constexpr float padding = 256.f; + + return (pos.x < 0 - padding || pos.x > Config::getWidth() + padding || + pos.y < 0 - padding || pos.y > Config::getHeight() + padding); + }; + + const auto makePBParticle = [this] { + Particle p; + + p.sprite.setTexture(assets.get<sf::Texture>("starParticle.png")); + p.sprite.setPosition( + {ssvu::getRndR(-64.f, Config::getWidth() + 64.f), -64.f}); + p.sprite.setRotation(ssvu::getRndR(0.f, 360.f)); + + const float scale = ssvu::getRndR(0.75f, 1.35f); + p.sprite.setScale({scale, scale}); + + sf::Color c = getColorMain(); + c.a = ssvu::getRndI(90, 145); + p.sprite.setColor(c); + + p.velocity = {ssvu::getRndR(-12.f, 12.f), ssvu::getRndR(4.f, 18.f)}; + p.angularVelocity = ssvu::getRndR(-6.f, 6.f); + + return p; + }; + + ssvu::eraseRemoveIf(particles, isOutOfBounds); + + for(Particle& p : particles) + { + sf::Sprite& sp = p.sprite; + sp.setPosition(sp.getPosition() + p.velocity * mFT); + sp.setRotation(sp.getRotation() + p.angularVelocity * mFT); + } + + if(mustSpawnPBParticles) + { + nextPBParticleSpawn -= mFT; + if(nextPBParticleSpawn <= 0.f) + { + particles.emplace_back(makePBParticle()); + nextPBParticleSpawn = 2.75f; + } + } +} + } // namespace hg diff --git a/src/SSVOpenHexagon/Core/HexagonGame.cpp b/src/SSVOpenHexagon/Core/HexagonGame.cpp index 93dbb537..c68fc9e5 100644 --- a/src/SSVOpenHexagon/Core/HexagonGame.cpp +++ b/src/SSVOpenHexagon/Core/HexagonGame.cpp @@ -345,6 +345,7 @@ void HexagonGame::newGame(const std::string& mPackId, const std::string& mId, // Events cleanup messageText.setString(""); + pbText.setString(""); // Event timeline cleanup eventTimeline.clear(); @@ -366,6 +367,12 @@ void HexagonGame::newGame(const std::string& mPackId, const std::string& mId, effectTimelineManager.clear(); mustChangeSides = false; + // Particles cleanup + pbTextGrowth = 0.f; + mustSpawnPBParticles = false; + nextPBParticleSpawn = 0.f; + particles.clear(); + // FPSWatcher reset fpsWatcher.reset(); // if(Config::getOfficial()) fpsWatcher.enable(); @@ -486,7 +493,24 @@ void HexagonGame::death(bool mForce) return; } - assets.playSound("gameOver.ogg", ssvs::SoundPlayer::Mode::Abort); + const bool isPersonalBest = + !inReplay() && + (status.getTimeSeconds() > assets.getLocalScore(getLocalValidator( + levelData->id, difficultyMult))); + + if(isPersonalBest) + { + pbText.setString("NEW PERSONAL BEST!"); + mustSpawnPBParticles = true; + + // TODO: change sound + assets.playSound("gameOver.ogg", ssvs::SoundPlayer::Mode::Abort); + } + else + { + assets.playSound("gameOver.ogg", ssvs::SoundPlayer::Mode::Abort); + } + runLuaFunctionIfExists<void>("onDeath"); status.flashEffect = 255; @@ -508,8 +532,7 @@ void HexagonGame::death(bool mForce) // Gather player's Personal Best std::string pbStr = "("; - if(status.getTimeSeconds() > - assets.getLocalScore(getLocalValidator(levelData->id, difficultyMult))) + if(isPersonalBest) { pbStr += "New PB!)"; } diff --git a/src/SSVOpenHexagon/Core/MenuGame.cpp b/src/SSVOpenHexagon/Core/MenuGame.cpp index 7e69f19f..9bc0bc95 100644 --- a/src/SSVOpenHexagon/Core/MenuGame.cpp +++ b/src/SSVOpenHexagon/Core/MenuGame.cpp @@ -3872,9 +3872,16 @@ void MenuGame::drawLevelSelectionRightSide( // Therefore pack labels must be drawn above everything else (aka must // be drawn last). - renderTextCentered(isFavoriteLevels() ? "PRESS F2 TO SHOW ALL LEVELS" - : "PRESS F2 TO SHOW FAVORITE LEVELS", - txtSelectionSmall.font, {w / 2.f, 5.f}); + static std::string smallTextContents; + + smallTextContents.clear(); + smallTextContents += isFavoriteLevels() + ? "PRESS F2 TO SHOW ALL LEVELS" + : "PRESS F2 TO SHOW FAVORITE LEVELS"; + smallTextContents += "\nHOLD FOCUS TO JUMP BETWEEN PACKS"; + + renderTextCentered( + smallTextContents, txtSelectionSmall.font, {w / 2.f, 5.f}); //---------------------------------------- // LEVELS LIST |