Created
August 13, 2023 15:06
-
-
Save voidproc/211db9df9d46c8c37a9123f30eb2a6a4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# include <Siv3D.hpp> // OpenSiv3D v0.6.11 | |
struct PolygonHighlightEffect : IEffect | |
{ | |
Array<TrailMotion> trails; | |
Polygon polygon; | |
PolygonHighlightEffect(const Polygon& targetPolygon) | |
: polygon{ targetPolygon } | |
{ | |
constexpr std::array<ColorF, 3> colors = { Palette::White, Palette::Magenta, Palette::Cyan }; | |
for (int iTrail : step(3)) | |
{ | |
trails << TrailMotion{} | |
.setLifeTime(DisplayTime + 0.5 * iTrail) | |
.setColor(ColorF{ colors[iTrail], 1 - 0.2 * iTrail }) | |
.setSizeFunction([=](double timeSec) { | |
const double size = 2 + 3 * iTrail; | |
const double sizeScale1 = timeSec < LifeTime ? 1 : 0; | |
const double sizeScale2 = timeSec < 0.1 ? timeSec / 0.1 : 1; | |
const double displayTimeScaled = DisplayTime * 0.7; | |
const double sizeScale3 = timeSec < displayTimeScaled ? 1 : EaseInExpo(1 - ((timeSec - displayTimeScaled) / (LifeTime - displayTimeScaled))); | |
return size * sizeScale1 * sizeScale2 * sizeScale3; | |
}) | |
.setPositionFunction([&](double timeSec) { | |
const double t = Min(timeSec, DisplayTime); | |
const double t0_1 = t / (DisplayTime * 0.8); | |
const auto& vertices = polygon.outer(); | |
const int index1 = ((int)(t0_1 * vertices.size())) % vertices.size(); | |
const int index2 = (index1 + 1) % vertices.size(); | |
double tmp; | |
const double lerpFactor = modf(t0_1 * vertices.size(), &tmp); | |
const auto v = vertices[index1].lerp(vertices[index2], EaseInExpo(lerpFactor)); | |
return v; | |
}); | |
} | |
} | |
bool update(double timeSec) override | |
{ | |
for (auto& trail : trails) | |
{ | |
trail.update(); | |
} | |
{ | |
const ScopedRenderStates2D blend{ BlendState::Additive }; | |
for (const auto& trail : trails) | |
{ | |
trail.draw(); | |
} | |
} | |
return timeSec < 3.0; | |
} | |
private: | |
inline static constexpr double DisplayTime = 0.3; | |
inline static constexpr double LifeTime = 1.0; | |
}; | |
void Main() | |
{ | |
Scene::SetBackground(ColorF{ 0 }); | |
const RectF rect{ Arg::center = Scene::CenterF().movedBy(-160, -140), SizeF{ 200, 180 }}; | |
const Circle circle{ Scene::CenterF().movedBy(160, 140), 100 }; | |
const Polygon star = Shape2D::Star(128, Scene::CenterF().movedBy(-160, 140)); | |
const Polygon nstar = Shape2D::NStar(12, 128, 96, Scene::CenterF().movedBy(160, -140)); | |
Effect effect; | |
while (System::Update()) | |
{ | |
rect.drawFrame(1, 0, Palette::Silver); | |
circle.drawFrame(1, 0, Palette::Silver); | |
star.drawFrame(1, Palette::Silver); | |
nstar.drawFrame(1, Palette::Silver); | |
if (rect.leftClicked()) | |
{ | |
effect.add<PolygonHighlightEffect>(rect.asPolygon()); | |
} | |
else if (circle.leftClicked()) | |
{ | |
effect.add<PolygonHighlightEffect>(circle.asPolygon()); | |
} | |
else if (star.leftClicked()) | |
{ | |
effect.add<PolygonHighlightEffect>(star); | |
} | |
else if (nstar.leftClicked()) | |
{ | |
effect.add<PolygonHighlightEffect>(nstar); | |
} | |
else if (Scene::Rect().leftClicked()) | |
{ | |
effect.add<PolygonHighlightEffect>(Scene::Rect().stretched(-1).asPolygon()); | |
} | |
effect.update(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
result_polygon_highlight.mp4