<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="ステージ\選曲\曲パネルビュー.cs" />
<Compile Include="設定\Config.cs" />
<Compile Include="SSTException.cs" />
<Compile Include="StrokeStyleT.cs" />
<Compile Include="ステージ\演奏\演奏ステージ.cs" />
<Compile Include="ステージ\結果\結果ステージ.cs" />
<Compile Include="ステージ\起動\起動ステージ.cs" />
- <Compile Include="ステージ\選曲\曲パネルビュー.cs" />
+ <Compile Include="ステージ\選曲\曲パネルビューD2D.cs" />
<Compile Include="ステージ\選曲\選曲ステージ.cs" />
<Compile Include="フォルダ.cs" />
<Compile Include="ユーザ\XML.cs" />
{
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 )
{
// オフセット と カーソル位置.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--;
}
//-----------------
// 描画。
- Debug.Assert( null != StrokeStyleT.ユーザ管理 );
- Debug.Assert( null != StrokeStyleT.ユーザ管理.現在選択されているユーザ );
- Debug.Assert( null != StrokeStyleT.ユーザ管理.現在選択されているユーザ.曲ツリーのルートノード );
+ Debug.Assert( null != StrokeStyleT.ユーザ管理?.現在選択されているユーザ?.曲ツリーのルートノード );
var 曲リスト管理 = StrokeStyleT.曲ツリー管理;
var 曲リスト = 曲リスト管理.現在選択されているノード?.親ノード.子ノードリスト ?? 曲リスト管理.現在の管理対象ツリー.子ノードリスト;
}
else
{
- this.パネルを一枚描画する(
- dr,
- 描画する曲,
- パネル位置,
- これはカーソル位置のパネルである: false );
+ this.パネルを一枚描画する( dr, 描画する曲, パネル位置, これはカーソル位置のパネルである: false );
}
// 次のノードへ移動。(選択ノードは移動しない。)
//-----------------
#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;
/// <summary>
/// 左上隅のパネルを (0,0) とした時の、カーソル位置の座標。
/// 負数も可。
/// </summary>
protected SharpDX.Point カーソル位置 = new SharpDX.Point( 4, 1 );
-
/// <summary>
- /// -63~63。パネルの表示位置を、負数は 左 へ、正数は 右 へずらす 。(正負と左右の対応に注意。)
+ /// -63~63。パネル全体の表示位置を、負数は 左 へ、正数は 右 へずらす 。(正負と左右の対応に注意。)
/// </summary>
/// <remarks>
/// ±64 は、パネル1列分を表すサイズ。
/// </remarks>
- protected int 曲パネルのY軸回転オフセット = 0;
+ protected int パネル全体のY軸回転オフセット = 0;
- protected bool 活性化した直後である = false;
- protected FDK.カウンタ.定間隔進行 横スクロール用カウンタ = null;
- protected readonly FDK.メディア.画像 Nullパネルの画像;
+ /// <summary>
+ /// パネルを一枚(ノード画像とタイトル画像)を、指定したパネル位置に描画する。
+ /// </summary>
+ /// <param name="パネルノード">null 可。</param>
+ protected void パネルを一枚描画する( デバイスリソース dr, 曲.Node パネルノード, SharpDX.Point パネル位置, bool これはカーソル位置のパネルである = false )
+ {
+ /*
+ if( null != パネルノード )
+ {
+ // ノード画像を表示する。
+ // タイトル文字列画像を表示する。
+ }
+ else
+ */
+ {
+ // Nullパネル画像を表示する。
+ this.Nullパネルの画像.進行描画する( dr, SharpDX.Matrix.Identity );
+ }
+ }
}
}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using FDK.メディア;
+
+namespace SST.ステージ.選曲
+{
+ /// <summary>
+ /// 曲パネルリスト(9列3行)を表示する。
+ /// </summary>
+ /// <remarks>
+ /// 静止時の可視範囲は、左右両端の1列を除いた7列3行。
+ /// 左右両端の列は、静止時は画面外に位置しており、左右スクロール中にのみ画面内に一部が表示される。
+ /// 「カーソル」は、常に、曲パネル内のいずれか1枚の曲を選択している。
+ /// カーソルは、初期状態では中央の曲を選択しており、本クラスのメソッドを使って上下左右に移動することができる。
+ /// カーソルが選択している曲は強調表示(視覚効果として少し拡大して表示)される。
+ /// </remarks>
+ 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 );
+ }
+
+ /// <summary>
+ /// 左上隅のパネルを (0,0) とした時の、カーソル位置の座標。
+ /// 負数も可。
+ /// </summary>
+ protected SharpDX.Point カーソル位置 = new SharpDX.Point( 4, 1 );
+
+ /// <summary>
+ /// -63~63。パネルの表示位置を、負数は 左 へ、正数は 右 へずらす 。(正負と左右の対応に注意。)
+ /// </summary>
+ /// <remarks>
+ /// ±64 は、パネル1列分を表すサイズ。
+ /// </remarks>
+ protected int 曲パネルのY軸回転オフセット = 0;
+
+ protected bool 活性化した直後である = false;
+ protected FDK.カウンタ.定間隔進行 横スクロール用カウンタ = null;
+ protected readonly FDK.メディア.画像 Nullパネルの画像;
+ }
+}
}
}
- 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;
}
}