✨
Siv3D | 今すぐ使えるエフェクト集
1. 色の付いたバブル
# include <Siv3D.hpp> // OpenSiv3D v0.6.2
struct BubbleEffect : IEffect
{
struct Bubble
{
Vec2 offset;
double startTime;
double scale;
ColorF color;
};
Vec2 m_pos;
Array<Bubble> m_bubbles;
BubbleEffect(const Vec2& pos, double baseHue)
: m_pos{ pos }
{
for (int32 i = 0; i < 8; ++i)
{
Bubble bubble{
.offset = RandomVec2(Circle{30}),
.startTime = Random(-0.3, 0.1), // 登場の時間差
.scale = Random(0.1, 1.2),
.color = HSV{ baseHue + Random(-30.0, 30.0) }
};
m_bubbles << bubble;
}
}
bool update(double t) override
{
for (const auto& bubble : m_bubbles)
{
const double t2 = (bubble.startTime + t);
if (not InRange(t2, 0.0, 1.0))
{
continue;
}
const double e = EaseOutExpo(t2);
Circle{ (m_pos + bubble.offset + (bubble.offset * 4 * t)), (e * 40 * bubble.scale) }
.draw(ColorF{ bubble.color, 0.15 })
.drawFrame((30.0 * (1.0 - e) * bubble.scale), bubble.color);
}
return (t < 1.3);
}
};
void Main()
{
Effect effect;
while (System::Update())
{
if (MouseL.down())
{
effect.add<BubbleEffect>(Cursor::PosF(), Random(0.0, 360.0));
}
{
const ScopedRenderStates2D blend{ BlendState::Additive };
effect.update();
}
}
}
v0.4.3
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
struct BubbleEffect : IEffect
{
struct Bubble
{
Vec2 offset;
double startTime;
double scale;
ColorF color;
};
Vec2 m_pos;
Array<Bubble> m_bubbles;
BubbleEffect(const Vec2& pos, double baseHue)
: m_pos(pos)
{
for (int32 i = 0; i < 8; ++i)
{
Bubble bubble{
.offset = RandomVec2(Circle(30)),
.startTime = Random(-0.3, 0.1),
.scale = Random(0.1, 1.2),
.color = HSV(baseHue + Random(-30.0, 30.0))
};
m_bubbles << bubble;
}
}
bool update(double t) override
{
for (const auto& bubble : m_bubbles)
{
const double t2 = (bubble.startTime + t);
if (!InRange(t2, 0.0, 1.0))
{
continue;
}
const double e = EaseOutExpo(t2);
Circle(m_pos + bubble.offset + (bubble.offset * 4 * t), e * 40 * bubble.scale)
.draw(ColorF(bubble.color, 0.15))
.drawFrame(30.0 * (1.0 - e) * bubble.scale, bubble.color);
}
return (t < 1.3);
}
};
void Main()
{
Window::Resize(1280, 720);
Effect effect;
while (System::Update())
{
if (MouseL.down())
{
effect.add<BubbleEffect>(Cursor::PosF(), Random(0.0, 360.0));
}
{
ScopedRenderStates2D blend(BlendState::Additive);
effect.update();
}
}
}
2. 水平フレア
# include <Siv3D.hpp> // OpenSiv3D v0.6.2
struct VerticalFlare : IEffect
{
Vec2 m_pos;
Texture m_texture;
VerticalFlare(const Vec2& pos, const Texture& texture)
: m_pos{ pos }
, m_texture{ texture } {}
bool update(double t) override
{
t /= 0.5;
const double e = EaseInSine(t);
const double scale = 6.0 * (1.0 - e);
double s = 1.0;
for (auto i : step(9))
{
m_texture.scaled(scale * Vec2{ s, (1.0 / s) })
.drawAt(m_pos, HSV{ (120 * i), 0.4 });
s *= 1.25;
}
return (t < 1.0);
}
};
void Main()
{
Window::Resize(1280, 720);
Effect effect;
const Texture texture{ U"example/particle.png", TextureDesc::Mipped };
while (System::Update())
{
if (MouseL.down())
{
effect.add<VerticalFlare>(Cursor::PosF(), texture);
}
{
const ScopedRenderStates2D blend{ BlendState::Additive };
effect.update();
}
}
}
v0.4.3
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
struct VerticalFlare : IEffect
{
Vec2 m_pos;
Texture m_texture;
VerticalFlare(const Vec2& pos, const Texture& texture)
: m_pos(pos)
, m_texture(texture) {}
bool update(double t) override
{
t /= 0.5;
const double e = EaseInSine(t);
const double scale = 6.0 * (1.0 - e);
double s = 1.0;
for (auto i : step(9))
{
m_texture.scaled(scale * Vec2(s, 1.0 / s))
.drawAt(m_pos, HSV(120 * i, 0.4));
s *= 1.25;
}
return (t < 1.0);
}
};
void Main()
{
Window::Resize(1280, 720);
Effect effect;
const Texture texture(U"example/particle.png");
while (System::Update())
{
if (MouseL.down())
{
effect.add<VerticalFlare>(Cursor::PosF(), texture);
}
{
ScopedRenderStates2D blend(BlendState::Additive);
effect.update();
}
}
}
3. 飛び散る星
# include <Siv3D.hpp> // OpenSiv3D v0.6.2
struct StarEffect : IEffect
{
static constexpr Vec2 Gravity{ 0, 160 };
struct Star
{
Vec2 start;
Vec2 velocity;
ColorF color;
};
Array<Star> m_stars;
StarEffect(const Vec2& pos, double baseHue)
{
for (int32 i = 0; i < 6; ++i)
{
const Vec2 velocity = RandomVec2(Circle{ 60 });
Star star{
.start = (pos + velocity),
.velocity = velocity,
.color = HSV{ baseHue + Random(-20.0, 20.0) },
};
m_stars << star;
}
}
bool update(double t) override
{
t /= 0.4;
for (auto& star : m_stars)
{
const Vec2 pos = star.start
+ star.velocity * t + 0.5 * t * t * Gravity;
const double angle = (pos.x * 3_deg);
Shape2D::Star((30 * (1.0 - t)), pos, angle)
.draw(star.color);
}
return (t < 1.0);
}
};
void Main()
{
Effect effect;
Circle circle{ Scene::Center(), 30 };
double baseHue = 180.0;
while (System::Update())
{
if (circle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
if (circle.leftClicked())
{
effect.add<StarEffect>(Cursor::PosF(), baseHue);
circle.center = RandomVec2(Scene::Rect().stretched(-80));
baseHue = Random(0.0, 360.0);
}
circle.draw(HSV{ baseHue });
effect.update();
}
}
v0.4.3
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
struct StarEffect : IEffect
{
static constexpr Vec2 Gravity{ 0, 160 };
struct Star
{
Vec2 start;
Vec2 velocity;
ColorF color;
};
Array<Star> m_stars;
StarEffect(const Vec2& pos, double baseHue)
{
for (int32 i = 0; i < 6; ++i)
{
const Vec2 velocity = RandomVec2(Circle(60));
Star star{
.start = pos + velocity,
.velocity = velocity,
.color = HSV(baseHue + Random(-20.0, 20.0)),
};
m_stars << star;
}
}
bool update(double t) override
{
t /= 0.4;
for (auto& star : m_stars)
{
const Vec2 pos = star.start
+ star.velocity * t + 0.5 * t * t * Gravity;
const double angle = pos.x * 5_deg;
Shape2D::Star(30 * (1 - t), pos, angle)
.draw(star.color);
}
return (t < 1.0);
}
};
void Main()
{
Window::Resize(1280, 720);
Effect effect;
Circle circle(Scene::Center(), 30);
double baseHue = 180.0;
while (System::Update())
{
if (circle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
if (circle.leftClicked())
{
effect.add<StarEffect>(Cursor::PosF(), baseHue);
circle.center = RandomVec2(Scene::Rect().stretched(-80));
baseHue = Random(0.0, 360.0);
}
circle.draw(HSV(baseHue));
effect.update();
}
}
4. クリック時のパーティクルエフェクト
# include <Siv3D.hpp> // OpenSiv3D v0.6.2
struct TouchEffect : IEffect
{
struct Particle
{
Vec2 velocity;
Vec2 start;
double r;
double angle;
bool cw;
ColorF color;
};
struct Star
{
Vec2 velocity;
Vec2 start;
double angle;
double scale;
ColorF color;
};
Vec2 m_pos;
Array<Particle> m_particles;
Array<Star> m_stars;
explicit TouchEffect(const Vec2& pos)
: m_pos{ pos }
{
for (int32 i = 0; i < 200; ++i)
{
const Vec2 velocoty = RandomVec2(28.0);
Particle particle{
.velocity = velocoty,
.start = velocoty,
.r = Random(6.0, 12.0),
.angle = Random(360_deg),
.cw = RandomBool(),
.color = HSV{ Random(50.0, 70.0), 0.4, 1.0 },
};
m_particles << particle;
}
for (int32 i = 0; i < 8; ++i)
{
const Vec2 velocoty = RandomVec2(28.0);
Star star{
.velocity = velocoty,
.start = (velocoty + RandomVec2(2.0)),
.angle = Random(360_deg),
.scale = Random(0.6, 1.4),
.color = HSV{ Random(50.0, 70.0), 0.4, 1.0 },
};
m_stars << star;
}
}
bool update(double t) override
{
t /= 0.45;
const double r = (30 + t * 30);
const ColorF outer = HSV{ 180, 0.8, 1.0, 0.0 };
const ColorF inner = HSV{ 180, 0.8, 1.0, (0.5 * (1.0 - t)) };
Circle{ m_pos, r }
.drawFrame(10, 0, outer, inner)
.drawFrame(0, 10, inner, outer);
for (const auto& particle : m_particles)
{
const Vec2 pos = m_pos
+ particle.start
+ Circular(particle.r, particle.angle + t * 120_deg * (particle.cw ? 1 : -1))
+ (particle.velocity * t - 0.5 * t * t * particle.velocity);
const double rOuter = (1.0 * (1.0 - t) * 2);
const double rInner = (0.8 * (1.0 - t) * 2);
Shape2D::NStar(2, rOuter, rInner, pos, particle.angle)
.draw(particle.color);
}
for (const auto& star : m_stars)
{
const Vec2 pos = m_pos
+ star.start
+ (star.velocity * t - 0.5 * t * t * star.velocity);
const double rOuter = (12 * (1.0 - t) * star.scale);
const double rInner = (4 * (1.0 - t) * star.scale);
const double angle = (star.angle + t * 90_deg);
Shape2D::NStar(4, rOuter, rInner, pos, angle)
.draw(star.color);
}
return (t < 1.0);
}
};
void Main()
{
Effect effect;
while (System::Update())
{
if (MouseL.down())
{
effect.add<TouchEffect>(Cursor::PosF());
}
{
const ScopedRenderStates2D blend{ BlendState::Additive };
effect.update();
}
}
}
v0.4.3
# include <Siv3D.hpp> // OpenSiv3D v0.4.3
struct ParticleClickEffect : IEffect
{
struct Particle
{
Vec2 velocity;
Vec2 start;
double r;
double angle;
bool cw;
ColorF color;
};
struct Star
{
Vec2 velocity;
Vec2 start;
double angle;
double scale;
ColorF color;
};
Vec2 m_pos;
Array<Particle> m_particles;
Array<Star> m_stars;
ParticleClickEffect(const Vec2& pos)
: m_pos(pos)
{
for (int32 i = 0; i < 200; ++i)
{
const Vec2 velocoty = RandomVec2(28.0);
Particle particle{
.velocity = velocoty,
.start = velocoty,
.r = Random(6.0, 12.0),
.angle = Random(360_deg),
.cw = RandomBool(),
.color = HSV(Random(50.0, 70.0), 0.4, 1.0),
};
m_particles << particle;
}
for (int32 i = 0; i < 8; ++i)
{
const Vec2 velocoty = RandomVec2(28.0);
Star star{
.velocity = velocoty,
.start = velocoty + RandomVec2(2.0),
.angle = Random(360_deg),
.scale = Random(0.6, 1.4),
.color = HSV(Random(50.0, 70.0), 0.4, 1.0),
};
m_stars << star;
}
}
bool update(double t) override
{
t /= 0.45;
const double r = 30 + t * 30;
const ColorF outer = HSV(180, 0.8, 1.0, 0.0);
const ColorF inner = HSV(180, 0.8, 1.0, 0.5 * (1 - t));
Circle(m_pos, r)
.drawFrame(10, 0, outer, inner)
.drawFrame(0, 10, inner, outer);
for (const auto& particle : m_particles)
{
const Vec2 pos = m_pos
+ particle.start
+ Circular(particle.r, particle.angle + t * 120_deg * (particle.cw ? 1 : -1))
+ (particle.velocity * t - 0.5 * t * t * particle.velocity);
Shape2D::NStar(2, 1.0 * (1 - t) * 2, 0.8 * (1 - t) * 2, pos, particle.angle)
.draw(particle.color);
}
for (const auto& star : m_stars)
{
const Vec2 pos = m_pos
+ star.start
+ (star.velocity * t - 0.5 * t * t * star.velocity);
Shape2D::NStar(4, 12 * (1 - t) * star.scale, 4 * (1 - t) * star.scale,
pos, star.angle + t * 90_deg)
.draw(star.color);
}
return (t < 1.0);
}
};
void Main()
{
Window::Resize(1280, 720);
Effect effect;
while (System::Update())
{
if (MouseL.down())
{
effect.add<ParticleClickEffect>(Cursor::PosF());
}
{
ScopedRenderStates2D blend(BlendState::Additive);
effect.update();
}
}
}
Discussion