シーン遷移トランジション#2
https://gyazo.com/06a1e764bb8ae23fccdb7eda072830e1
説明
なんだかちょっといい感じのトランジションをクラス化しました。
コード
code:Transition.cpp
# include <Siv3D.hpp>
class SplitCircle
{
private:
Size area; //描画エリア
Circle split1, split2; //背景のスプリット
Array<Circle> arcs; //回る線の本体
Array<double> arcStartDeg; //回る線のスタート位置
Array<double> arcRotateDeg; //回る線の回る量
Array<double> arcLength; //回る線の長さ
Array<double> arcWeight; //回る線の太さ
Array<double> delay; //回る線の回るディレイ
Array<ColorF> arcColors; //回る線の色
public:
SplitCircle() = default;
SplitCircle(Size size, int32 quantity = 20)
: area{ size }
{
init(quantity);
}
//初期化関数
void init(int32 quantity = 20)
{
//メンバ初期化
arcs.clear();
arcStartDeg.clear();
arcRotateDeg.clear();
arcLength.clear();
arcWeight.clear();
delay.clear();
arcColors.clear();
//ベースとなる色相(これの±40の色になる)
double baseColor = Random(0, 360);
for (auto i : step(quantity))
{
//乱数で各要素を決める
arcStartDeg << Random(0_deg, 360_deg);
double rotate = Random(120_deg, 1080_deg);
arcRotateDeg << rotate;
arcLength << rotate / 3;
arcWeight << Random(1, 6);
delay << Random(0.0, 0.3);
arcColors << HSV(baseColor + Random(-40, 40), Random(0.3, 0.8), 1);
arcs << Circle{ Scene::Center(), Random(100, (area.x + area.y) / 3) };
}
//背景のスプリット
split1 = Circle{ Scene::Center(), area.x + area.y };
split2 = Circle{ Scene::Center(), area.x + area.y };
}
void drawTransitionIn(double t) const
{
//イージング
double e = EaseInOutQuart(t);
//背景のスプリット描画
split1.drawPie(180_deg - t * 70_deg, 180_deg - e * 180_deg, Palette::Darkgrey);
split2.drawPie(-t * 70_deg, 180_deg - e * 180_deg, Palette::Darkgrey);
double t2 = t + 1.0;
for (auto i : step(arcs.size()))
{
//ディレイを考慮したイージング
double e = EaseInOutQuart(Min(1.0 - delayi + t, 1.0)); //回る線を描画
arcsi.drawArc(arcStartDegi - e * arcRotateDegi - (t2 - delayi) * 70_deg, sin(e * Math::Pi) * arcLengthi, arcWeighti, arcWeighti, arcColorsi); }
}
void drawTransitionOut(double t) const
{
//イージング
double e = EaseInOutQuart(t);
//背景のスプリット描画
split1.drawPie(70_deg - t * 70_deg, -e * 180_deg, Palette::Darkgrey);
split2.drawPie(250_deg - t * 70_deg, -e * 180_deg, Palette::Darkgrey);
for (auto i : step(arcs.size()))
{
//ディレイを考慮したイージング
double e = EaseInOutQuart(Max(t - delayi, 0.0)); //回る線を描画
arcsi.drawArc(LineStyle::RoundCap, arcStartDegi - e * arcRotateDegi - (t - delayi) * 70_deg, sin(e * Math::Pi) * arcLengthi, arcWeighti, arcWeighti, arcColorsi); }
}
};
使い方
code:Main.cpp
# include <Siv3D.hpp>
/*
ここにトランジションクラス
*/
struct GameData
{
SplitCircle sc{ Scene::Size() };
};
using App = SceneManager<String, GameData>;
class Scene1 : public App::Scene
{
public:
Scene1(const InitData& init)
: IScene{ init } {}
void update() override
{
if (KeyEnter.down())
{
getData().sc.init();
changeScene(U"Scene2", 2.5s);
}
}
void draw() const override
{
FontAsset(U"SampleFont")(U"Scene1").drawAt(Scene::Center(), Palette::Red);
}
void drawFadeIn(double t) const override
{
draw();
getData().sc.drawTransitionIn(t);
}
void drawFadeOut(double t) const override
{
draw();
getData().sc.drawTransitionOut(t);
}
};
class Scene2 : public App::Scene
{
public:
Scene2(const InitData& init)
: IScene{ init } {}
void update() override
{
if (KeyEnter.down())
{
getData().sc.init();
changeScene(U"Scene1");
}
}
void draw() const override
{
FontAsset(U"SampleFont")(U"Scene2").drawAt(Scene::Center(), Palette::Limegreen);
}
void drawFadeIn(double t) const override
{
draw();
getData().sc.drawTransitionIn(t);
}
void drawFadeOut(double t) const override
{
draw();
getData().sc.drawTransitionOut(t);
}
};
void Main()
{
FontAsset::Register(U"SampleFont", 60, Typeface::Heavy);
Window::Resize(1280, 720);
App manager;
manager.add<Scene1>(U"Scene1");
manager.add<Scene2>(U"Scene2");
while (System::Update())
{
if (!manager.update())
{
break;
}
}
}
作者
たのれん