summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVittorio Romeo <vittorio.romeo@outlook.com>2021-03-01 18:21:39 +0000
committerVittorio Romeo <vittorio.romeo@outlook.com>2021-03-01 18:21:39 +0000
commit191560755ad7b1d0d9f1d7d825221d6274a8be49 (patch)
treecc246598815dba6ec631a4c55724a838b7d2b5a5
parent5248d3546eb363fc6de0808d54efd470625d0227 (diff)
Add basic particle system and success particlesimprove_tutorial
-rw-r--r--_RELEASE/Assets/assets.json3
-rw-r--r--_RELEASE/Assets/starParticle.pngbin0 -> 2105 bytes
-rw-r--r--_RELEASE/Packs/hypercube/Scripts/commonpatterns.lua8
-rw-r--r--_RELEASE/Packs/workshopexample/Scripts/commonpatterns.lua82
-rw-r--r--_RELEASE/Temp/example/Scripts/commonpatterns.lua82
-rw-r--r--include/SSVOpenHexagon/Core/HexagonGame.hpp25
-rw-r--r--src/SSVOpenHexagon/Core/HGGraphics.cpp55
-rw-r--r--src/SSVOpenHexagon/Core/HGUpdate.cpp62
-rw-r--r--src/SSVOpenHexagon/Core/HexagonGame.cpp29
-rw-r--r--src/SSVOpenHexagon/Core/MenuGame.cpp13
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
new file mode 100644
index 00000000..8af2fb7a
--- /dev/null
+++ b/_RELEASE/Assets/starParticle.png
Binary files differ
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