using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using FDK.メディア; using FDK.カウンタ; namespace SST.ステージ { /// /// フェードインを描画する。 /// /// /// 全画面を覆うように指定された画像をタイル描画し、その透明度を徐々に薄くしていくことで徐々に下地が見えてくるフェードインを実現する。 /// パネル画像は、呼び出しもとから提供されたものを使う。 /// class フェードイン : FDK.Activity { public bool 開始されている { get => ( null != this._透明度カウンタ ); } public bool 開始されていない { get => !( this.開始されている ); } public bool 完了した { get => this._透明度カウンタ.終了値に達した; } public bool 完了していない { get => !( this.完了した ); } public フェードイン( float 総フェード時間sec ) { Debug.Assert( 0.0f < 総フェード時間sec ); this._総フェード時間sec = 総フェード時間sec; } protected override void On活性化( グラフィックデバイス gd ) { this._透明度カウンタ = null; // 動的子Activityの追加 this.子リスト.Add( this._マップ画像 = new 描画可能画像( new SharpDX.Size2( (int) gd.設計画面サイズ.Width, (int) gd.設計画面サイズ.Height ) ) ); } protected override void On非活性化( グラフィックデバイス gd ) { // 動的子Activityの削除 this.子リスト.Remove( this._マップ画像 ); } public void 開始する() { int 最初の値 = 0; int 最後の値 = 100; long 値をひとつ増加させるのにかける時間ms = (long) ( this._総フェード時間sec * 1000f / ( 最後の値 - 最初の値 ) ); this._透明度カウンタ = new Counter( 最初の値, 最後の値, 値をひとつ増加させるのにかける時間ms ); } public void 進行描画する( グラフィックデバイス gd, 画像 フェードインに使うタイル画像 ) { Debug.Assert( this.活性化している ); if( this.開始されていない ) return; // (1) マップ画像(設計画面サイズ)に、タイル画像を敷き詰める。 this._マップ画像.画像へ描画する( gd, ( dc ) => { dc.Transform = SharpDX.Matrix3x2.Identity; // D2DBatchDraw() で DPX→PX に設定されている Transform を等倍スケール(Identity)に上書き。 var タイルサイズ = フェードインに使うタイル画像.サイズ; int タイル枚数X = (int) ( gd.設計画面サイズ.Width / タイルサイズ.Width ) + 1; // 剰余は切り捨てられるので +1 。 int タイル枚数Y = (int) ( gd.設計画面サイズ.Height / タイルサイズ.Height ) + 1; for( int x = 0; x < タイル枚数X; x++ ) { for( int y = 0; y < タイル枚数Y; y++ ) { // 画像.描画する() は使わない。(上書きした Transform がまた上書きされてしまうので。) dc.DrawBitmap( bitmap: フェードインに使うタイル画像.Bitmap, destinationRectangle: new SharpDX.RectangleF( x * タイルサイズ.Width, y * タイルサイズ.Height, タイルサイズ.Width, タイルサイズ.Height ), opacity: 1f, interpolationMode: SharpDX.Direct2D1.InterpolationMode.Linear, sourceRectangle: null, erspectiveTransformRef: null ); } } } ); // (2) マップ画像を画面(物理画面サイズ)に描画する。 this._マップ画像.描画する( gd, 不透明度0to1: 1f - this._透明度カウンタ.現在値の割合 ); } private float _総フェード時間sec = 1.0f; private Counter _透明度カウンタ = null; /// /// タイル画像は、一度この画像に敷き詰めてから描画する。 /// → タイルを個々に描画すると、設計画面サイズから物理画面サイズへの変換の際に、誤差によってスキマが生じることがある。 /// private 描画可能画像 _マップ画像 = null; } }