From e85843855288ea6a6f1f796f75168d2d3648050e Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E3=81=8F=E3=81=BE=E3=81=8B=E3=81=BF=E5=B7=A5=E6=88=BF?= Date: Tue, 4 Oct 2016 16:13:31 +0900 Subject: [PATCH] =?utf8?q?D2D=E7=89=88=E3=82=92=E6=94=B9=E5=90=8D=E3=81=97?= =?utf8?q?=E3=80=81=E6=96=B0=E3=81=97=E3=81=8F=E6=9B=B2=E3=83=91=E3=83=8D?= =?utf8?q?=E3=83=AB=E3=83=93=E3=83=A5=E3=83=BC=E3=82=AF=E3=83=A9=E3=82=B9?= =?utf8?q?=E3=82=92=E8=BF=BD=E5=8A=A0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- StrokeStyleT/StrokeStyleT.csproj | 3 +- .../ステージ/選曲/曲パネルビュー.cs | 306 +++++------------ .../選曲/曲パネルビューD2D.cs | 380 +++++++++++++++++++++ .../ステージ/選曲/選曲ステージ.cs | 8 +- 4 files changed, 472 insertions(+), 225 deletions(-) create mode 100644 StrokeStyleT/ステージ/選曲/曲パネルビューD2D.cs diff --git a/StrokeStyleT/StrokeStyleT.csproj b/StrokeStyleT/StrokeStyleT.csproj index 38163df..d251a3f 100644 --- a/StrokeStyleT/StrokeStyleT.csproj +++ b/StrokeStyleT/StrokeStyleT.csproj @@ -88,6 +88,7 @@ + @@ -115,7 +116,7 @@ - + diff --git a/StrokeStyleT/ステージ/選曲/曲パネルビュー.cs b/StrokeStyleT/ステージ/選曲/曲パネルビュー.cs index 8c5ad13..2959e02 100644 --- a/StrokeStyleT/ステージ/選曲/曲パネルビュー.cs +++ b/StrokeStyleT/ステージ/選曲/曲パネルビュー.cs @@ -20,7 +20,55 @@ namespace SST.ステージ.選曲 { public 曲パネルビュー() { - this.子リスト.Add( this.Nullパネルの画像 = new 画像( @"$(Static)\images\選曲パネル.png" ) ); + this.子リスト.Add( this.Nullパネルの画像 = new テクスチャ( @"$(Static)\images\選曲パネル.png" ) ); + } + public void カーソルを上に移動する() + { + if( 0 < this.カーソル位置.Y ) + { + this.カーソル位置.Y--; + } + else + { + this.カーソル位置.X--; + this.カーソル位置.Y = 2; + } + + // カーソルと一緒に、選択曲も移動する。 + StrokeStyleT.曲ツリー管理.前のノードを選択する(); + } + public void カーソルを下に移動する() + { + if( 2 > this.カーソル位置.Y ) + { + this.カーソル位置.Y++; + } + else + { + this.カーソル位置.X++; + this.カーソル位置.Y = 0; + } + + // カーソルと一緒に、選択曲も移動する。 + StrokeStyleT.曲ツリー管理.次のノードを選択する(); + } + public void カーソルを左に移動する() + { + this.カーソル位置.X--; // 制限なし + + // カーソルと一緒に、選択曲も移動する。 + StrokeStyleT.曲ツリー管理.前のノードを選択する(); + StrokeStyleT.曲ツリー管理.前のノードを選択する(); + StrokeStyleT.曲ツリー管理.前のノードを選択する(); + } + public void カーソルを右に移動する() + { + this.カーソル位置.X++; // 制限なし + + // カーソルと一緒に、選択曲も移動する。 + StrokeStyleT.曲ツリー管理.次のノードを選択する(); + StrokeStyleT.曲ツリー管理.次のノードを選択する(); + StrokeStyleT.曲ツリー管理.次のノードを選択する(); } protected override void On活性化( デバイスリソース dr ) { @@ -60,32 +108,32 @@ namespace SST.ステージ.選曲 // オフセット と カーソル位置.X を更新する。 if( ( 4 > this.カーソル位置.X ) || - ( ( 4 == this.カーソル位置.X ) && ( 0 > this.曲パネルのY軸回転オフセット ) ) ) + ( ( 4 == this.カーソル位置.X ) && ( 0 > this.パネル全体のY軸回転オフセット ) ) ) { - #region " パネルは、左から右へ、移動する。" + #region " (A) パネルは、左から右へ、移動する。" //----------------- - this.曲パネルのY軸回転オフセット += オフセットの加減算速度; + this.パネル全体のY軸回転オフセット += オフセットの加減算速度; // 1列分移動した - if( 64 <= this.曲パネルのY軸回転オフセット ) + if( 64 <= this.パネル全体のY軸回転オフセット ) { - this.曲パネルのY軸回転オフセット -= 64; // 0 付近に戻る + this.パネル全体のY軸回転オフセット -= 64; // 0 付近に戻る this.カーソル位置.X++; } //----------------- #endregion } else if( ( 4 < this.カーソル位置.X ) || - ( ( 4 == this.カーソル位置.X ) && ( 0 < this.曲パネルのY軸回転オフセット ) ) ) + ( ( 4 == this.カーソル位置.X ) && ( 0 < this.パネル全体のY軸回転オフセット ) ) ) { - #region " パネルは、右から左へ、移動する。" + #region " (B) パネルは、右から左へ、移動する。" //----------------- - this.曲パネルのY軸回転オフセット -= オフセットの加減算速度; + this.パネル全体のY軸回転オフセット -= オフセットの加減算速度; // 1列分移動した - if( -64 >= this.曲パネルのY軸回転オフセット ) + if( -64 >= this.パネル全体のY軸回転オフセット ) { - this.曲パネルのY軸回転オフセット += 64; // 0 付近に戻る + this.パネル全体のY軸回転オフセット += 64; // 0 付近に戻る this.カーソル位置.X--; } //----------------- @@ -97,9 +145,7 @@ namespace SST.ステージ.選曲 // 描画。 - Debug.Assert( null != StrokeStyleT.ユーザ管理 ); - Debug.Assert( null != StrokeStyleT.ユーザ管理.現在選択されているユーザ ); - Debug.Assert( null != StrokeStyleT.ユーザ管理.現在選択されているユーザ.曲ツリーのルートノード ); + Debug.Assert( null != StrokeStyleT.ユーザ管理?.現在選択されているユーザ?.曲ツリーのルートノード ); var 曲リスト管理 = StrokeStyleT.曲ツリー管理; var 曲リスト = 曲リスト管理.現在選択されているノード?.親ノード.子ノードリスト ?? 曲リスト管理.現在の管理対象ツリー.子ノードリスト; @@ -137,11 +183,7 @@ namespace SST.ステージ.選曲 } else { - this.パネルを一枚描画する( - dr, - 描画する曲, - パネル位置, - これはカーソル位置のパネルである: false ); + this.パネルを一枚描画する( dr, 描画する曲, パネル位置, これはカーソル位置のパネルである: false ); } // 次のノードへ移動。(選択ノードは移動しない。) @@ -163,218 +205,42 @@ namespace SST.ステージ.選曲 //----------------- #endregion } - public void カーソルを上に移動する() - { - if( 0 < this.カーソル位置.Y ) - { - this.カーソル位置.Y--; - } - else - { - this.カーソル位置.X--; - this.カーソル位置.Y = 2; - } - - // カーソルと一緒に、選択曲も移動する。 - StrokeStyleT.曲ツリー管理.前のノードを選択する(); - } - public void カーソルを下に移動する() - { - Debug.Assert( this.活性化している ); - - if( 2 > this.カーソル位置.Y ) - { - this.カーソル位置.Y++; - } - else - { - this.カーソル位置.X++; - this.カーソル位置.Y = 0; - } - - // カーソルと一緒に、選択曲も移動する。 - StrokeStyleT.曲ツリー管理.次のノードを選択する(); - } - public void カーソルを左に移動する() - { - Debug.Assert( this.活性化している ); - - this.カーソル位置.X--; // 制限なし - - // カーソルと一緒に、選択曲も移動する。 - StrokeStyleT.曲ツリー管理.前のノードを選択する(); - StrokeStyleT.曲ツリー管理.前のノードを選択する(); - StrokeStyleT.曲ツリー管理.前のノードを選択する(); - } - public void カーソルを右に移動する() - { - Debug.Assert( this.活性化している ); - - this.カーソル位置.X++; // 制限なし - - // カーソルと一緒に、選択曲も移動する。 - StrokeStyleT.曲ツリー管理.次のノードを選択する(); - StrokeStyleT.曲ツリー管理.次のノードを選択する(); - StrokeStyleT.曲ツリー管理.次のノードを選択する(); - } - - protected void パネルを一枚描画する( - デバイスリソース dr, - 曲.Node パネルノード, // null 可 - SharpDX.Point パネル位置, - bool これはカーソル位置のパネルである = false ) - { - const float カーソル位置のパネルの拡大率 = 1.25f; - - #region " 2D変換行列を作成する(ノード画像、タイトル画像共通)。" - //----------------- - // 全体的に、画面中央のちょい上に移動する。 - float ちょい上dpx = -70.0f; // ステージ台とパネルが接触しない程度の位置へ。 - var 変換行列2Dpx = dr.行列を単位変換するDPXtoPX( - SharpDX.Matrix3x2.Translation( - dr.設計画面サイズdpx.Width / 2.0f, - dr.設計画面サイズdpx.Height / 2.0f + ちょい上dpx ) ); - - if( これはカーソル位置のパネルである ) - { - // 拡大する分だけ表示座標を移動する。 - 変換行列2Dpx *= dr.行列を単位変換するDPXtoPX( - SharpDX.Matrix3x2.Translation( - -パネルサイズdpx.全体dpx.Width * ( カーソル位置のパネルの拡大率 - 1.0f ) / 2.0f, - -パネルサイズdpx.全体dpx.Height * ( カーソル位置のパネルの拡大率 - 1.0f ) / 2.0f ) ); - } - //----------------- - #endregion - - // パネル位置にオフセットを加味し、横位置の割合を算出する。 - const float 列間隔の角度 = 0.104f; // 等間隔 - float 横位置割合 = 0.920f - ( パネル位置.X + ( this.曲パネルのY軸回転オフセット / 64.0f ) ) * 列間隔の角度; - - var 変換行列3Dpx = SharpDX.Matrix.Identity; - - if( null != パネルノード ) - { - #region " 3D変換行列を作成してノード画像を表示する。" - //----------------- - 変換行列3Dpx = SharpDX.Matrix.Scaling( - x: パネルサイズdpx.画像領域dpx.Width / パネルノード.ノード画像サイズdpx.Width, // ノード画像を設計値サイズに拡大縮小する。 - y: パネルサイズdpx.画像領域dpx.Height / パネルノード.ノード画像サイズdpx.Height, - z: 1.0f ); - - // カーソル位置なら拡大する。 - if( これはカーソル位置のパネルである ) - 変換行列3Dpx *= SharpDX.Matrix.Scaling( カーソル位置のパネルの拡大率 ); - - // 曲面変換。 - 変換行列3Dpx *= this.横位置割合からパネルの変換行列を算出して返す( dr, 横位置割合, パネル位置.Y ); - - // 描画。 - パネルノード.ノード画像を描画する( dr, 変換行列2Dpx, 変換行列3Dpx ); - //----------------- - #endregion - #region " 3D変換行列を作成してタイトル画像を表示する。" - //----------------- - 変換行列3Dpx = SharpDX.Matrix.Scaling( - x: パネルサイズdpx.タイトル領域dpx.Width / パネルノード.タイトル画像サイズdpx.Width, // タイトル画像を設計値サイズに拡大縮小する。 - y: パネルサイズdpx.タイトル領域dpx.Height / パネルノード.タイトル画像サイズdpx.Height, - z: 1.0f ); - - // カーソル位置なら拡大する。 - if( これはカーソル位置のパネルである ) - 変換行列3Dpx *= SharpDX.Matrix.Scaling( カーソル位置のパネルの拡大率 ); - - // 曲面変換。 - 変換行列3Dpx *= this.横位置割合からパネルの変換行列を算出して返す( dr, 横位置割合, パネル位置.Y ); - - // 描画。 - パネルノード.タイトル画像を描画する( dr, 変換行列2Dpx, 変換行列3Dpx ); - //----------------- - #endregion - } - else - { - #region " 3D変換行列を作成してノード画像を表示する。" - //----------------- - 変換行列3Dpx = SharpDX.Matrix.Scaling( - x: パネルサイズdpx.画像領域dpx.Width / this.Nullパネルの画像.サイズdpx.Width, // ノード画像を設計値サイズに拡大縮小する。 - y: パネルサイズdpx.画像領域dpx.Height / this.Nullパネルの画像.サイズdpx.Height, - z: 1.0f ); - - // カーソル位置なら拡大する。 - if( これはカーソル位置のパネルである ) - 変換行列3Dpx *= SharpDX.Matrix.Scaling( カーソル位置のパネルの拡大率 ); - - // 曲面変換。 - 変換行列3Dpx *= this.横位置割合からパネルの変換行列を算出して返す( dr, 横位置割合, パネル位置.Y ); - - // 描画。 - this.Nullパネルの画像.進行描画する( dr, 変換行列2Dpx, 変換行列3Dpx ); - //----------------- - #endregion - } - } - - protected SharpDX.Matrix 横位置割合からパネルの変換行列を算出して返す( デバイスリソース dr, float 横位置割合, int Y位置0to2 ) - { - // 原点が画像の左上隅から画像の中央へ来るように移動。 - var 変換行列3Dpx = SharpDX.Matrix.Translation( - x: -( パネルサイズdpx.全体dpx.Width * dr.拡大率DPXtoPX横方法 / 2.0f ), - y: -( パネルサイズdpx.全体dpx.Height * dr.拡大率DPXtoPX縦方向 / 2.0f ), - z: 0.0f ); - - // 縦方向の移動(上、中、下段のいずれかへ)。 - 変換行列3Dpx *= SharpDX.Matrix.Translation( - 0.0f, - ( ( ( Y位置0to2 - 1 ) * 230.0f ) ) * dr.拡大率DPXtoPX縦方向, // 1行は 230 dpx - 0.0f ); - - // Y軸回転半径分、画面奥に移動。 - 変換行列3Dpx *= SharpDX.Matrix.Translation( - 0.0f, - 0.0f, - -1000.0f * dr.拡大率DPXtoPX横方法 ); // 回転半径は 1000 dpx; Direct2D では、画面手前ほどZ軸がプラス。なお、Z 軸だがここでは 横方向 の拡大率を使用。 - - // Y軸回転。 - 変換行列3Dpx *= SharpDX.Matrix.RotationY( - (float) Math.PI * ( 横位置割合 - 0.5f ) ); - - // 画面に近いので、全体的に画面の奥へ移動。 - 変換行列3Dpx *= SharpDX.Matrix.Translation( - 0.0f, - 0.0f, - 950.0f * dr.拡大率DPXtoPX横方法 ); // 移動量 950 dpx; なお、Z 軸だがここでは 横方向 の拡大率を使用。 - - // 射影変換。 - 変換行列3Dpx *= FDK.Utilities.D2DPerspectiveProjection( - dr.設計画面サイズdpx.Height * 1.67f * dr.拡大率DPXtoPX横方法 ); // 深さは約 1800 [px; 縦1080px時]; Direc2D では、パラメータは深さのみ。なお、(同上 - - return 変換行列3Dpx; - } - - // 設計定数 - protected struct パネルサイズdpx - { - public static readonly SharpDX.Size2F 全体dpx = new SharpDX.Size2F( 314f, 220f ); - public static readonly SharpDX.RectangleF 画像領域dpx = new SharpDX.RectangleF( 0f, 0f, 313f, 137f ); - public static readonly SharpDX.RectangleF タイトル領域dpx = new SharpDX.RectangleF( 0f, 138f, 313f, 219f ); - } + protected const float カーソル位置のパネルの拡大率 = 1.25f; + protected bool 活性化した直後である = false; + protected readonly FDK.メディア.テクスチャ Nullパネルの画像; + protected FDK.カウンタ.定間隔進行 横スクロール用カウンタ = null; /// /// 左上隅のパネルを (0,0) とした時の、カーソル位置の座標。 /// 負数も可。 /// protected SharpDX.Point カーソル位置 = new SharpDX.Point( 4, 1 ); - /// - /// -63~63。パネルの表示位置を、負数は 左 へ、正数は 右 へずらす 。(正負と左右の対応に注意。) + /// -63~63。パネル全体の表示位置を、負数は 左 へ、正数は 右 へずらす 。(正負と左右の対応に注意。) /// /// /// ±64 は、パネル1列分を表すサイズ。 /// - protected int 曲パネルのY軸回転オフセット = 0; + protected int パネル全体のY軸回転オフセット = 0; - protected bool 活性化した直後である = false; - protected FDK.カウンタ.定間隔進行 横スクロール用カウンタ = null; - protected readonly FDK.メディア.画像 Nullパネルの画像; + /// + /// パネルを一枚(ノード画像とタイトル画像)を、指定したパネル位置に描画する。 + /// + /// null 可。 + protected void パネルを一枚描画する( デバイスリソース dr, 曲.Node パネルノード, SharpDX.Point パネル位置, bool これはカーソル位置のパネルである = false ) + { + /* + if( null != パネルノード ) + { + // ノード画像を表示する。 + // タイトル文字列画像を表示する。 + } + else + */ + { + // Nullパネル画像を表示する。 + this.Nullパネルの画像.進行描画する( dr, SharpDX.Matrix.Identity ); + } + } } } diff --git a/StrokeStyleT/ステージ/選曲/曲パネルビューD2D.cs b/StrokeStyleT/ステージ/選曲/曲パネルビューD2D.cs new file mode 100644 index 0000000..15cd759 --- /dev/null +++ b/StrokeStyleT/ステージ/選曲/曲パネルビューD2D.cs @@ -0,0 +1,380 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using FDK.メディア; + +namespace SST.ステージ.選曲 +{ + /// + /// 曲パネルリスト(9列3行)を表示する。 + /// + /// + /// 静止時の可視範囲は、左右両端の1列を除いた7列3行。 + /// 左右両端の列は、静止時は画面外に位置しており、左右スクロール中にのみ画面内に一部が表示される。 + /// 「カーソル」は、常に、曲パネル内のいずれか1枚の曲を選択している。 + /// カーソルは、初期状態では中央の曲を選択しており、本クラスのメソッドを使って上下左右に移動することができる。 + /// カーソルが選択している曲は強調表示(視覚効果として少し拡大して表示)される。 + /// + class 曲パネルビューD2D : FDK.Activity + { + public 曲パネルビューD2D() + { + this.子リスト.Add( this.Nullパネルの画像 = new 画像( @"$(Static)\images\選曲パネル.png" ) ); + } + protected override void On活性化( デバイスリソース dr ) + { + this.活性化した直後である = true; + } + protected override void On非活性化( デバイスリソース dr ) + { + } + public void 進行描画する( デバイスリソース dr ) + { + // 進行。 + + if( this.活性化した直後である ) + { + this.活性化した直後である = false; + this.横スクロール用カウンタ = new FDK.カウンタ.定間隔進行(); + } + else + { + this.横スクロール用カウンタ.経過時間の分だけ進行する( 8, () => { + + int オフセットの加減算速度 = 1; + + #region " カーソルが中央から遠いほど速くなるよう、オフセットの加減算速度(絶対値)を計算する。" + //------------------ + int 距離 = Math.Abs( 4 - this.カーソル位置.X ); + if( 1 >= 距離 ) + オフセットの加減算速度 = 2; + else if( 4 >= 距離 ) + オフセットの加減算速度 = 4; + else if( 6 >= 距離 ) + オフセットの加減算速度 = 6; + else + オフセットの加減算速度 = 8; + //------------------ + #endregion + + // オフセット と カーソル位置.X を更新する。 + if( ( 4 > this.カーソル位置.X ) || + ( ( 4 == this.カーソル位置.X ) && ( 0 > this.曲パネルのY軸回転オフセット ) ) ) + { + #region " パネルは、左から右へ、移動する。" + //----------------- + this.曲パネルのY軸回転オフセット += オフセットの加減算速度; + + // 1列分移動した + if( 64 <= this.曲パネルのY軸回転オフセット ) + { + this.曲パネルのY軸回転オフセット -= 64; // 0 付近に戻る + this.カーソル位置.X++; + } + //----------------- + #endregion + } + else if( ( 4 < this.カーソル位置.X ) || + ( ( 4 == this.カーソル位置.X ) && ( 0 < this.曲パネルのY軸回転オフセット ) ) ) + { + #region " パネルは、右から左へ、移動する。" + //----------------- + this.曲パネルのY軸回転オフセット -= オフセットの加減算速度; + + // 1列分移動した + if( -64 >= this.曲パネルのY軸回転オフセット ) + { + this.曲パネルのY軸回転オフセット += 64; // 0 付近に戻る + this.カーソル位置.X--; + } + //----------------- + #endregion + } + + } ); + } + + // 描画。 + + Debug.Assert( null != StrokeStyleT.ユーザ管理 ); + Debug.Assert( null != StrokeStyleT.ユーザ管理.現在選択されているユーザ ); + Debug.Assert( null != StrokeStyleT.ユーザ管理.現在選択されているユーザ.曲ツリーのルートノード ); + + var 曲リスト管理 = StrokeStyleT.曲ツリー管理; + var 曲リスト = 曲リスト管理.現在選択されているノード?.親ノード.子ノードリスト ?? 曲リスト管理.現在の管理対象ツリー.子ノードリスト; + var 描画する曲 = 曲リスト管理.現在選択されているノード; // null 可 + var カーソル位置の曲 = (曲.Node) null; // null 可 + + #region " 左上隅パネルに対応する曲リストノードを検索する。" + //----------------- + int 現在のカーソルから左上隅までの差 = 0 - ( this.カーソル位置.X * 3 + this.カーソル位置.Y ); // 現在のカーソルの位置に、現在選択されている曲が対応するものとする。 + + if( 0 < 現在のカーソルから左上隅までの差 ) + { + // 曲リストを前方へたどる。 + for( int i = 0; i < 現在のカーソルから左上隅までの差; i++ ) + 描画する曲 = 描画する曲?.次のノード; + } + else + { + // 曲リストを後方へたどる。 + for( int i = 現在のカーソルから左上隅までの差; i < 0; i++ ) + 描画する曲 = 描画する曲?.前のノード; + } + //----------------- + #endregion + #region " 9×3枚の曲パネルを描画する。" + //----------------- + for( int i = 0; i < ( 9 * 3 ); i++ ) + { + var パネル位置 = new SharpDX.Point( i / 3, i % 3 ); + + if( パネル位置 == this.カーソル位置 ) + { + // カーソル位置にあるパネルは後で描画するので、覚えておく。 + カーソル位置の曲 = 描画する曲; + } + else + { + this.パネルを一枚描画する( + dr, + 描画する曲, + パネル位置, + これはカーソル位置のパネルである: false ); + } + + // 次のノードへ移動。(選択ノードは移動しない。) + 描画する曲 = 描画する曲?.次のノード; + } + //----------------- + #endregion + #region " カーソル位置のパネルを描画する。" + //----------------- + if( ( 0 <= this.カーソル位置.X ) && ( 9 > this.カーソル位置.X ) && + ( 0 <= this.カーソル位置.Y ) && ( 3 > this.カーソル位置.Y ) ) + { + this.パネルを一枚描画する( + dr, + カーソル位置の曲, // 先の for ループ内で取得済み。 + this.カーソル位置, + これはカーソル位置のパネルである: true ); + } + //----------------- + #endregion + } + public void カーソルを上に移動する() + { + if( 0 < this.カーソル位置.Y ) + { + this.カーソル位置.Y--; + } + else + { + this.カーソル位置.X--; + this.カーソル位置.Y = 2; + } + + // カーソルと一緒に、選択曲も移動する。 + StrokeStyleT.曲ツリー管理.前のノードを選択する(); + } + public void カーソルを下に移動する() + { + Debug.Assert( this.活性化している ); + + if( 2 > this.カーソル位置.Y ) + { + this.カーソル位置.Y++; + } + else + { + this.カーソル位置.X++; + this.カーソル位置.Y = 0; + } + + // カーソルと一緒に、選択曲も移動する。 + StrokeStyleT.曲ツリー管理.次のノードを選択する(); + } + public void カーソルを左に移動する() + { + Debug.Assert( this.活性化している ); + + this.カーソル位置.X--; // 制限なし + + // カーソルと一緒に、選択曲も移動する。 + StrokeStyleT.曲ツリー管理.前のノードを選択する(); + StrokeStyleT.曲ツリー管理.前のノードを選択する(); + StrokeStyleT.曲ツリー管理.前のノードを選択する(); + } + public void カーソルを右に移動する() + { + Debug.Assert( this.活性化している ); + + this.カーソル位置.X++; // 制限なし + + // カーソルと一緒に、選択曲も移動する。 + StrokeStyleT.曲ツリー管理.次のノードを選択する(); + StrokeStyleT.曲ツリー管理.次のノードを選択する(); + StrokeStyleT.曲ツリー管理.次のノードを選択する(); + } + + protected void パネルを一枚描画する( + デバイスリソース dr, + 曲.Node パネルノード, // null 可 + SharpDX.Point パネル位置, + bool これはカーソル位置のパネルである = false ) + { + const float カーソル位置のパネルの拡大率 = 1.25f; + + #region " 2D変換行列を作成する(ノード画像、タイトル画像共通)。" + //----------------- + // 全体的に、画面中央のちょい上に移動する。 + float ちょい上dpx = -70.0f; // ステージ台とパネルが接触しない程度の位置へ。 + var 変換行列2Dpx = dr.行列を単位変換するDPXtoPX( + SharpDX.Matrix3x2.Translation( + dr.設計画面サイズdpx.Width / 2.0f, + dr.設計画面サイズdpx.Height / 2.0f + ちょい上dpx ) ); + + if( これはカーソル位置のパネルである ) + { + // 拡大する分だけ表示座標を移動する。 + 変換行列2Dpx *= dr.行列を単位変換するDPXtoPX( + SharpDX.Matrix3x2.Translation( + -パネルサイズdpx.全体dpx.Width * ( カーソル位置のパネルの拡大率 - 1.0f ) / 2.0f, + -パネルサイズdpx.全体dpx.Height * ( カーソル位置のパネルの拡大率 - 1.0f ) / 2.0f ) ); + } + //----------------- + #endregion + + // パネル位置にオフセットを加味し、横位置の割合を算出する。 + const float 列間隔の角度 = 0.104f; // 等間隔 + float 横位置割合 = 0.920f - ( パネル位置.X + ( this.曲パネルのY軸回転オフセット / 64.0f ) ) * 列間隔の角度; + + var 変換行列3Dpx = SharpDX.Matrix.Identity; + + if( null != パネルノード ) + { + #region " 3D変換行列を作成してノード画像を表示する。" + //----------------- + 変換行列3Dpx = SharpDX.Matrix.Scaling( + x: パネルサイズdpx.画像領域dpx.Width / パネルノード.ノード画像サイズdpx.Width, // ノード画像を設計値サイズに拡大縮小する。 + y: パネルサイズdpx.画像領域dpx.Height / パネルノード.ノード画像サイズdpx.Height, + z: 1.0f ); + + // カーソル位置なら拡大する。 + if( これはカーソル位置のパネルである ) + 変換行列3Dpx *= SharpDX.Matrix.Scaling( カーソル位置のパネルの拡大率 ); + + // 曲面変換。 + 変換行列3Dpx *= this.横位置割合からパネルの変換行列を算出して返す( dr, 横位置割合, パネル位置.Y ); + + // 描画。 + パネルノード.ノード画像を描画する( dr, 変換行列2Dpx, 変換行列3Dpx ); + //----------------- + #endregion + #region " 3D変換行列を作成してタイトル画像を表示する。" + //----------------- + 変換行列3Dpx = SharpDX.Matrix.Scaling( + x: パネルサイズdpx.タイトル領域dpx.Width / パネルノード.タイトル画像サイズdpx.Width, // タイトル画像を設計値サイズに拡大縮小する。 + y: パネルサイズdpx.タイトル領域dpx.Height / パネルノード.タイトル画像サイズdpx.Height, + z: 1.0f ); + + // カーソル位置なら拡大する。 + if( これはカーソル位置のパネルである ) + 変換行列3Dpx *= SharpDX.Matrix.Scaling( カーソル位置のパネルの拡大率 ); + + // 曲面変換。 + 変換行列3Dpx *= this.横位置割合からパネルの変換行列を算出して返す( dr, 横位置割合, パネル位置.Y ); + + // 描画。 + パネルノード.タイトル画像を描画する( dr, 変換行列2Dpx, 変換行列3Dpx ); + //----------------- + #endregion + } + else + { + #region " 3D変換行列を作成してノード画像を表示する。" + //----------------- + 変換行列3Dpx = SharpDX.Matrix.Scaling( + x: パネルサイズdpx.画像領域dpx.Width / this.Nullパネルの画像.サイズdpx.Width, // ノード画像を設計値サイズに拡大縮小する。 + y: パネルサイズdpx.画像領域dpx.Height / this.Nullパネルの画像.サイズdpx.Height, + z: 1.0f ); + + // カーソル位置なら拡大する。 + if( これはカーソル位置のパネルである ) + 変換行列3Dpx *= SharpDX.Matrix.Scaling( カーソル位置のパネルの拡大率 ); + + // 曲面変換。 + 変換行列3Dpx *= this.横位置割合からパネルの変換行列を算出して返す( dr, 横位置割合, パネル位置.Y ); + + // 描画。 + this.Nullパネルの画像.進行描画する( dr, 変換行列2Dpx, 変換行列3Dpx ); + //----------------- + #endregion + } + } + + protected SharpDX.Matrix 横位置割合からパネルの変換行列を算出して返す( デバイスリソース dr, float 横位置割合, int Y位置0to2 ) + { + // 原点が画像の左上隅から画像の中央へ来るように移動。 + var 変換行列3Dpx = SharpDX.Matrix.Translation( + x: -( パネルサイズdpx.全体dpx.Width * dr.拡大率DPXtoPX横方法 / 2.0f ), + y: -( パネルサイズdpx.全体dpx.Height * dr.拡大率DPXtoPX縦方向 / 2.0f ), + z: 0.0f ); + + // 縦方向の移動(上、中、下段のいずれかへ)。 + 変換行列3Dpx *= SharpDX.Matrix.Translation( + 0.0f, + ( ( ( Y位置0to2 - 1 ) * 230.0f ) ) * dr.拡大率DPXtoPX縦方向, // 1行は 230 dpx + 0.0f ); + + // Y軸回転半径分、画面奥に移動。 + 変換行列3Dpx *= SharpDX.Matrix.Translation( + 0.0f, + 0.0f, + -1000.0f * dr.拡大率DPXtoPX横方法 ); // 回転半径は 1000 dpx; Direct2D では、画面手前ほどZ軸がプラス。なお、Z 軸だがここでは 横方向 の拡大率を使用。 + + // Y軸回転。 + 変換行列3Dpx *= SharpDX.Matrix.RotationY( + (float) Math.PI * ( 横位置割合 - 0.5f ) ); + + // 画面に近いので、全体的に画面の奥へ移動。 + 変換行列3Dpx *= SharpDX.Matrix.Translation( + 0.0f, + 0.0f, + 950.0f * dr.拡大率DPXtoPX横方法 ); // 移動量 950 dpx; なお、Z 軸だがここでは 横方向 の拡大率を使用。 + + // 射影変換。 + 変換行列3Dpx *= FDK.Utilities.D2DPerspectiveProjection( + dr.設計画面サイズdpx.Height * 1.67f * dr.拡大率DPXtoPX横方法 ); // 深さは約 1800 [px; 縦1080px時]; Direc2D では、パラメータは深さのみ。なお、(同上 + + return 変換行列3Dpx; + } + + // 設計定数 + protected struct パネルサイズdpx + { + public static readonly SharpDX.Size2F 全体dpx = new SharpDX.Size2F( 314f, 220f ); + public static readonly SharpDX.RectangleF 画像領域dpx = new SharpDX.RectangleF( 0f, 0f, 313f, 137f ); + public static readonly SharpDX.RectangleF タイトル領域dpx = new SharpDX.RectangleF( 0f, 138f, 313f, 219f ); + } + + /// + /// 左上隅のパネルを (0,0) とした時の、カーソル位置の座標。 + /// 負数も可。 + /// + protected SharpDX.Point カーソル位置 = new SharpDX.Point( 4, 1 ); + + /// + /// -63~63。パネルの表示位置を、負数は 左 へ、正数は 右 へずらす 。(正負と左右の対応に注意。) + /// + /// + /// ±64 は、パネル1列分を表すサイズ。 + /// + protected int 曲パネルのY軸回転オフセット = 0; + + protected bool 活性化した直後である = false; + protected FDK.カウンタ.定間隔進行 横スクロール用カウンタ = null; + protected readonly FDK.メディア.画像 Nullパネルの画像; + } +} diff --git a/StrokeStyleT/ステージ/選曲/選曲ステージ.cs b/StrokeStyleT/ステージ/選曲/選曲ステージ.cs index d24f8a7..24a43b7 100644 --- a/StrokeStyleT/ステージ/選曲/選曲ステージ.cs +++ b/StrokeStyleT/ステージ/選曲/選曲ステージ.cs @@ -112,9 +112,9 @@ namespace SST.ステージ.選曲 } } - protected readonly FDK.メディア.動画 背景動画 = new 動画( @"$(Static)\images\選曲画面BGV.mp4" ); - protected readonly FDK.メディア.画像 ステージ台 = new 画像( @"$(Static)\images\ステージ台.png" ); - protected readonly SST.ステージ.汎用.ドラムセット ドラムセット = new 汎用.ドラムセット(); - protected readonly 曲パネルビュー 曲パネルビュー = new 曲パネルビュー(); + protected FDK.メディア.動画 背景動画 = null; + protected FDK.メディア.画像 ステージ台 = null; + protected SST.ステージ.汎用.ドラムセット ドラムセット = null; + protected 曲パネルビュー 曲パネルビュー = null; } } -- 2.11.0