某青春ゲーム風クリックエフェクト
https://gyazo.com/a93a382f799a4a853cc0f8d76f91322a
説明
ブルーなアーカイブのタッチエフェクトっぽいものです。最近ハマってます。加算ブレンドの影響で背景色が明るいと凄いことになるので適時調整してください。
コード
code:TouchEffect.cpp
# include<Siv3D.hpp> // OpenSiv3D v0.6.10
struct BlueArchiveEffect : IEffect
{
struct Trigon
{
Vec2 basepos;
double r;
double angle;
double scale;
int max;
bool reverse;
ColorF color;
};
struct Trail
{
Circle circle;
double startdeg;
double enddeg;
ColorF color;
};
const RenderTexture gaussianA1{ Scene::Size() }, gaussianB1{ Scene::Size() };
const RenderTexture gaussianA4{ Scene::Size() / 4 }, gaussianB4{ Scene::Size() / 4 };
const RenderTexture gaussianA8{ Scene::Size() / 8 }, gaussianB8{ Scene::Size() / 8 };
Vec2 m_pos;
Array<Trigon> m_trigons;
Array<Trail> m_trails;
BlueArchiveEffect(const Vec2& pos)
:m_pos{ pos }
{
for (auto i : step(4))
{
Trigon trigon
{
.basepos = pos,
.r = 0,
.angle = Random(360_deg),
.scale = 0,
.max = 20 + Random(-3, 3),
.reverse = RandomBool(),
.color = ColorF(0.5, 0.7, 1),
};
m_trigons << trigon;
}
double deg = Random(360_deg);
for (auto i : step(2))
{
Trail trail
{
.circle = Circle{ pos, 0 },
.startdeg = deg,
.enddeg = 0_deg,
.color = ColorF(0.7, 0.8, 1, 1),
};
m_trails << trail;
}
}
void drawTrail(double t)
{
const double e = EaseOutExpo(t);
const double e2 = EaseOutExpo(t / 0.5);
const double q = EaseOutCubic(t);
double r = e * 23 + t * 5;
double s = 0;
if (t > 0.8) s = EaseOutSine((t - 0.8) / 0.5);
m_trails0.circle.drawArc(m_trails0.startdeg + 135_deg * s + 30_deg * t, m_trails0.enddeg + 70_deg * e2 + 50_deg * t - 135_deg * s, 0.75, 0.75, m_trails0.color); m_trails1.circle.drawArc(m_trails1.startdeg + 135_deg * s + 30_deg * t, -1 * (m_trails1.enddeg + 70_deg * e2 + 50_deg * t - 135_deg * s), 0.75, 0.75, m_trails1.color); {
const ScopedRenderTarget2D target{ gaussianA1.clear(ColorF{ 0.0 }) };
const ScopedRenderStates2D blend{ BlendState::Additive };
m_trails0.circle.drawArc(m_trails0.startdeg + 135_deg * s + 30_deg * t, m_trails0.enddeg + 70_deg * e2 + 50_deg * t - 135_deg * s, 1.75, 1.75, m_trails0.color); m_trails1.circle.drawArc(m_trails1.startdeg + 135_deg * s + 30_deg * t, -1 * (m_trails1.enddeg + 70_deg * e2 + 50_deg * t - 135_deg * s), 1.75, 1.75, m_trails1.color); }
Shader::GaussianBlur(gaussianA1, gaussianB1, gaussianA1);
Shader::Downsample(gaussianA1, gaussianA4);
Shader::GaussianBlur(gaussianA4, gaussianB4, gaussianA4);
Shader::Downsample(gaussianA4, gaussianA8);
Shader::GaussianBlur(gaussianA8, gaussianB8, gaussianA8);
const ScopedRenderStates2D blend{ BlendState::Additive };
gaussianA1.resized(Scene::Size()).draw(ColorF{ 1 });
gaussianA4.resized(Scene::Size()).draw(ColorF{ 0.6 });
gaussianA8.resized(Scene::Size()).draw(ColorF{ 0.4 });
}
void drawTrigon(double t)
{
const double e = EaseOutExpo(t);
double r = e * 23 + t * 5;
for (auto trigon : m_trigons)
{
if (t < 0.2)
{
trigon.scale = t * trigon.max;
trigon.color = ColorF(0.5, 0.7, 1, 1);
}
else
{
trigon.scale = trigon.max - (t - 0.2) * trigon.max;
if (t < 0.4) trigon.color = ColorF(0.5, 0.7, 1, 1);
else trigon.color = ColorF(0.4, 0.6, 1, 0.3 + 0.7 * Periodic::Square0_1(0.1));
}
Triangle{ OffsetCircular{ m_pos, r * 0.8 + t * 20, trigon.angle }, trigon.scale, trigon.reverse * 180_deg }.draw(trigon.color);
}
}
bool update(double t) override
{
t /= 0.35;
const double e = EaseOutExpo(t);
const double q = EaseOutCubic(t);
double r = e * 23 + t * 5;
Circle{ m_pos, r }.draw(ColorF(0.4, 0.5, 1, t < 0.7 ? (1 - q) * 1.1 + 0.3 : 0));
drawTrail(t);
{
const ScopedRenderStates2D blend{ BlendState::Additive };
drawTrigon(t);
}
return t < 1.3;
}
};
void Main()
{
Effect effect;
while (System::Update())
{
if (MouseL.down())
{
effect.add<BlueArchiveEffect>(Cursor::PosF());
}
effect.update();
}
}
作者
たのれん