using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using FDK.メディア; namespace SST.ステージ.演奏 { /// /// コンボのビュー。 /// いずれ コンボ クラスへ統合予定。 /// class コンボジャンプ : FDK.Activity { /// /// 表示する数値。新しい数値をここに上書きしていく。 /// public FDK.同期.RWLock 数値 { get; } /// /// false にすると非表示。 /// public FDK.同期.RWLock 表示する { get; } public コンボジャンプ() { this._スレッド間同期 = new ReaderWriterLockSlim( LockRecursionPolicy.SupportsRecursion ); this.数値 = new FDK.同期.RWLock( this._スレッド間同期, 0 ); this.表示する = new FDK.同期.RWLock( this._スレッド間同期, true ); this.子リスト.Add( this._数値と単位の画像 = new 画像( @"$(Static)\images\combo.png" ) ); // 180度分のジャンプY座標差分を算出。(i:{0 → 90 → 179} で、[i]:{0 → -15 → 0}) for( int i = 0; i < 180; i++ ) this._ジャンプ差分値[ i ] = (int) ( -15.0 * Math.Sin( SharpDX.MathUtil.DegreesToRadians( i ) ) ); } protected override void On活性化( デバイスリソース dr ) { this.数値.Value = 0; this._現在の数値 = 0; this._ジャンプインデックス値 = 99999; this._ジャンプインデックス進行 = new FDK.カウンタ.定間隔進行(); } protected override void On非活性化( デバイスリソース dr ) { } public void 進行描画する( デバイスリソース dr, float 中央Xdpx, float 下辺Ydpx, float 文字間隔dpx ) { // 進行。 #region " ジャンプインデックス値 の進行。" //----------------- if( 360 > this._ジャンプインデックス値 ) { this._ジャンプインデックス進行.経過時間の分だけ進行する( 間隔ms: 2, 定間隔処理: () => { if( 2000 > this._ジャンプインデックス値 ) this._ジャンプインデックス値 += 3; } ); } //----------------- #endregion #region " 数値が増加していればジャンプを開始する。" //----------------- if( this.数値.Value > this._現在の数値 ) { this._ジャンプインデックス値 = 0; this._ジャンプインデックス進行 = new FDK.カウンタ.定間隔進行(); } //----------------- #endregion this._現在の数値 = this.数値.Value; // 描画。 if( this.表示する.Value ) { // 数値と単位を表示。 var 位の数 = new int[ 10 ]; // 10桁もあれば足りるやろ int 桁数 = 0; #region " 現在の数値 の桁を 逆順に 位の数[] に格納する。(例:現在の数値=125 のとき 位の数 = { 5,2,1,0,0,0,0,0,0,0 }, 桁数 = 3 ) " //----------------- int n = this._現在の数値; while( ( 0 < n ) && ( 10 > 桁数 ) ) { 位の数[ 桁数 ] = n % 10; // 1の位を格納 n = ( n - ( n % 10 ) ) / 10; // 右へシフト(例: 12345 → 1234 ) 桁数++; } //----------------- #endregion #region " 単位文字の矩形(COMBO矩形) と 数字と単位を合わせた画像の全幅dpx を算出。" //----------------- var COMBO矩形 = this._文字矩形dpx[ 10 ]; float 数字と単位を合わせた画像の全幅dpx = this._文字矩形dpx[ 10 ].Width; for( int i = 0; i < 桁数; i++ ) 数字と単位を合わせた画像の全幅dpx += this._文字矩形dpx[ 位の数[ i ] ].Width; //----------------- #endregion #region " 位の数[] を、COMBO文字→ 1の位 → 10の位 … の順に、右から左へ向かって順番に表示する。" //----------------- float x = 中央Xdpx + ( 数字と単位を合わせた画像の全幅dpx / 2f ); // 右端X float y = 下辺Ydpx; int jump = this._ジャンプインデックス値 - ( 桁数 * _桁ごとのジャンプの遅れ ); // "COMBO" を表示。 x -= COMBO矩形.Width; this._数値と単位の画像.描画する( dr, x, ( 下辺Ydpx - COMBO矩形.Height ), _不透明度0to1, 転送元矩形dpx: COMBO矩形 ); // 数値を1の位から順に表示。 for( int i = 0; i < 桁数; i++ ) { var rc = this._文字矩形dpx[ 位の数[ i ] ]; x -= rc.Width + 文字間隔dpx; y = 下辺Ydpx - rc.Height; jump = this._ジャンプインデックス値 - ( ( ( 桁数 - i ) - 1 ) * _桁ごとのジャンプの遅れ ); if( ( 0 <= jump ) && ( 180 > jump ) ) y += this._ジャンプ差分値[ jump ]; this._数値と単位の画像.描画する( dr, x, y, _不透明度0to1, 転送元矩形dpx: rc ); } //----------------- #endregion } } private int _現在の数値 = -1; private FDK.メディア.画像 _数値と単位の画像 = null; private readonly List _文字矩形dpx = new List() { #region " [0]~[9]: '0'~'9', [10]:'COMBO' " //---------------- new SharpDX.RectangleF( 0, 0, 45, 70 ), new SharpDX.RectangleF( 45, 0, 45, 70 ), new SharpDX.RectangleF( 90, 0, 45, 70 ), new SharpDX.RectangleF( 135, 0, 45, 70 ), new SharpDX.RectangleF( 180, 0, 45, 70 ), new SharpDX.RectangleF( 0, 70, 45, 70 ), new SharpDX.RectangleF( 45, 70, 45, 70 ), new SharpDX.RectangleF( 90, 70, 45, 70 ), new SharpDX.RectangleF( 135, 70, 45, 70 ), new SharpDX.RectangleF( 180, 70, 45, 70 ), new SharpDX.RectangleF( 0, 140, 90, 32 ), //---------------- #endregion }; private const int _桁ごとのジャンプの遅れ = 50; // 1桁につき 50 インデックス遅れる private const float _不透明度0to1 = 0.7f; private int _ジャンプインデックス値 = 9999; private int[] _ジャンプ差分値 = new int[ 180 ]; private FDK.カウンタ.定間隔進行 _ジャンプインデックス進行 = null; private System.Threading.ReaderWriterLockSlim _スレッド間同期 = null; } }