2017年7月25日火曜日

【Storyboard】立体的演出【Storybrew】

難易度: Advanced
範囲: Parameter, Vector Scale, Loop等

初めに.
そもそも、osuのStoryboardはXY平面上で動作しているため、立体的な処理が出来ません。ですが、ちょっとした工夫をすればある程度立体的な表現をすることが出来るようになります。

Paramete (FlipH, FlipV)画像を反転させる働きをします。
Vector Scale (ScaleVec):X, Yそれぞれの拡大率を設定します。

演出01.
これらのコマンドを組み合わせてみましょう。

        public override void Generate()
        {
      var layer = GetLayer("");
            var BG = layer.CreateSprite("SB/bg_1.jpg", OsbOrigin.TopLeft);

            var startTime = 175627;
            var endTime = 233912;
            var beat = Beatmap.GetTimingPointAt(startTime).BeatDuration;

            BG.Scale(startTime - beat, endTime, 480/768.0 * 1.1, 480/768.0);
            BG.Fade(startTime - beat, startTime, 0, 1); 
            BG.Fade(endTime, endTime + beat, 1, 0);
            BG.Move(startTime, -107, 0);

            var n_sakura = 500;
            var sakura = new OsbSprite[n_sakura];

            for (var i = 0; i < n_sakura; i++){
                if (i % 2 == 0){sakura[i] = layer.CreateSprite("SB/sakura_1.png");}
                else {sakura[i] = layer.CreateSprite("SB/sakura_2.png");}

                var sakuraStart = Random(startTime - beat, endTime - beat);
                var sakuraTime = Random(3000, 8000);
                var sakuraEnd = sakuraStart + sakuraTime;
                var Ys = Random(50, 600);
                var Ym = Random(-400, -50);
                double Ss = Random(40, 75); Ss /= 100.0;
                double Srx = Random(-6, 6) * Math.PI;
                var Srz = Random(1, 8);

                sakura[i].Fade(sakuraStart, sakuraEnd, 1, 1);
                sakura[i].Scale(sakuraStart, Ss);
                sakura[i].Rotate(sakuraStart, sakuraEnd, 0, Srx);
                sakura[i].MoveX(sakuraStart, sakuraEnd, -120, 800);
                sakura[i].MoveY(sakuraStart, sakuraEnd, Ys, Ys + Ym);
                sakura[i].Additive(sakuraStart, sakuraStart);

                if(Srz > 0)
                {
                    sakura[i].StartLoopGroup(sakuraStart, Srz);
                    sakura[i].ScaleVec(OsbEasing.InSine, 0, (sakuraTime / Srz) / 2, Ss, Ss, Ss, 0);
                    sakura[i].FlipV((sakuraTime / Srz) / 2, (sakuraTime / Srz) /2);
                    sakura[i].ScaleVec(OsbEasing.OutSine, (sakuraTime / Srz) / 2, (sakuraTime / Srz), Ss, 0, Ss, Ss);
                    sakura[i].EndGroup();
                }
            }


先ほどの2コマンドとRotateを組み合わせることによって二軸回転をさせています。現実的にはこのような動きはしないのですが、SBの演出としては十分でしょう。
最後のIF内にあるLoop処理が特徴的です。LoopGroupの記述方法は公式wikiを参照してください。




演出02.
Scaleを第三の軸, Z座標として扱うことが可能です。サイズを大きくすれば近づく、小さくすれば遠くなるのと同じような見え方をします。遠近法的なアレです。
具体例は割愛。

演出03.
Animationに頼る方法。その方が楽な場合もあるので覚えていても良いと思います。


補足.
var beat = Beatmap.GetTimingPointAt(startTime).BeatDuration;
公式wikiにはBeatmap Dataのページに載っています。
Beatmap.GetTimingPointAt(time)でtimeにおけるデータを取得します。今回の場合、BeatDurationと続けることで一拍の長さを変数"beat"に入れています。

var BG = layer.CreateSprite("SB/bg_1.jpg", OsbOrigin.TopLeft);
OsbOriginは重心の設定だと導入編で説明しました。今回の場合はTopLeft, 左上が重心となっています。





0 件のコメント:

コメントを投稿