summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVittorio Romeo <vittorio.romeo@outlook.com>2021-11-25 02:31:44 +0000
committerVittorio Romeo <vittorio.romeo@outlook.com>2021-11-25 02:31:44 +0000
commit37a5fbf2d47782d039f38bb34837d4247ba0e16b (patch)
treebde27cd677bdd9a2361a234fa4ac4cea7260eb8a
parente810d924f3ac6c3c3418e0fbf7f09d1995984f3d (diff)
Implement "swap ready sound", "swap particles", and "show swap blinking effect"
-rw-r--r--_RELEASE/Assets/assets.json3
-rw-r--r--include/SSVOpenHexagon/Components/CPlayer.hpp4
-rw-r--r--include/SSVOpenHexagon/Core/HexagonGame.hpp22
-rw-r--r--src/SSVOpenHexagon/Components/CPlayer.cpp15
-rw-r--r--src/SSVOpenHexagon/Core/HGGraphics.cpp17
-rw-r--r--src/SSVOpenHexagon/Core/HGUpdate.cpp117
-rw-r--r--src/SSVOpenHexagon/Core/HexagonGame.cpp25
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())