using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using SharpDX;
using FDK;
using FDK.メディア;
using FDK.カウンタ;
using SSTFormat.v3;
namespace SST.ステージ.演奏
{
class ヒットランク : Activity
{
public ヒットランク()
{
// すべてのヒットランク画像を子リストに追加。
foreach( var kvp in this._ヒットランク画像 )
this.子リスト.Add( kvp.Value );
}
public void 表示開始( 表示レーン種別 laneType, ヒットランク種別 hitRankType )
{
if( laneType == 表示レーン種別.Unknown )
return;
// レーンに対応する進行描画コンテキストを更新し、表示を開始するためのパラメータを設定する。
if( this._表示レーンto進行描画コンテキスト.ContainsKey( laneType ) ) // すでにあったら、
this._表示レーンto進行描画コンテキスト.Remove( laneType ); // 削除してから、
this._表示レーンto進行描画コンテキスト.Add( // 追加。
laneType,
new 進行描画コンテキスト() {
ヒットランク種別 = hitRankType,
進行カウンタ = new FDK.カウンタ.Counter( 最初の値: 0, 最後の値: 300, 値をひとつ増加させるのにかける時間ms: 1 ), // カウント開始(=表示開始)
X方向拡大率 = 1f,
Y方向拡大率 = 1f,
相対X座標 = 0,
相対Y座標 = 0,
透明度0to1 = 1f,
} );
}
public void 表示開始( チップ種別 chipType, ヒットランク種別 hitRankType )
{
var laneType = App.ユーザ管理.選択されているユーザ.オプション設定.ドラムとチップと入力の対応表[ chipType ].表示レーン種別;
if( laneType != 表示レーン種別.Unknown )
this.表示開始( laneType, hitRankType );
}
protected override void On活性化( グラフィックデバイス gd )
{
// すべての表示レーンについて、進行描画コンテキストを生成する。
this._表示レーンto進行描画コンテキスト = new Dictionary<表示レーン種別, 進行描画コンテキスト>();
foreach( 表示レーン種別 laneType in Enum.GetValues(typeof( 表示レーン種別 ) ) )
this._表示レーンto進行描画コンテキスト.Add( laneType, new 進行描画コンテキスト() );
}
protected override void On非活性化( グラフィックデバイス gd )
{
this._表示レーンto進行描画コンテキスト.Clear();
}
public void 進行描画する( グラフィックデバイス gd, float レーンフレームの左端 )
{
#region " 進行 "
//----------------
foreach( 表示レーン種別 lane in Enum.GetValues( typeof( 表示レーン種別 ) ) )
{
var context = this._表示レーンto進行描画コンテキスト[ lane ];
if( context.進行カウンタ.停止中である )
continue; // カウンタが停止中 → このレーンについては何もしない。
if( context.進行カウンタ.終了値に達した )
{
#region " 進行カウンタが終了値に達したら停止 → 表示完了。"
//----------------
context.進行カウンタ.一時停止する();
continue;
//----------------
#endregion
}
if( context.ヒットランク種別 != ヒットランク種別.MISS )
{
#region " (A) Perfect, Great, Good, Poor, Auto のアニメーション進行。"
//-----------------
if( context.進行カウンタ.現在値 < 50 )
{
// (B-a) 0~49
context.X方向拡大率 = 1.0f + ( 1.0f * ( 1.0f - ( context.進行カウンタ.現在値 / 50.0f ) ) );
context.Y方向拡大率 = context.進行カウンタ.現在値 / 50.0f;
context.相対X座標 = 0;
context.相対Y座標 = 0;
context.透明度0to1 = 1.0f;
}
else if( context.進行カウンタ.現在値 < 130 )
{
// (B-b) 50~129
context.X方向拡大率 = 1.0f;
context.Y方向拡大率 = 1.0f;
context.相対X座標 = 0;
context.相対Y座標 = ( ( context.進行カウンタ.現在値 % 6 ) == 0 ) ? ( App.乱数.Next( 6 ) - 3 ) : context.相対Y座標;
context.透明度0to1 = 1.0f;
}
else if( context.進行カウンタ.現在値 < 240 )
{
// (B-c) 130~239
context.X方向拡大率 = 1.0f;
context.Y方向拡大率 = 1.0f;
context.相対X座標 = 0;
context.相対Y座標 = 0;
context.透明度0to1 = 1.0f;
}
else
{
// (B-d) 240~300
context.X方向拡大率 = 1.0f;
context.Y方向拡大率 = 1.0f - ( ( 1.0f * ( context.進行カウンタ.現在値 - 240 ) ) / 60.0f );
context.相対X座標 = 0;
context.相対Y座標 = 0;
context.透明度0to1 = 1.0f;
}
//-----------------
#endregion
}
else
{
#region " (B) Miss のアニメーション進行だけ他とは違ってたり。"
//-----------------
if( context.進行カウンタ.現在値 < 50 )
{
// (A-a) 0~49
context.X方向拡大率 = 1.0f;
context.Y方向拡大率 = context.進行カウンタ.現在値 / 50.0f;
context.相対X座標 = 0;
context.相対Y座標 = 0;
context.透明度0to1 = 1.0f;
}
else if( context.進行カウンタ.現在値 < 200 )
{
// (A-b) 50~199
context.X方向拡大率 = 1.0f;
context.Y方向拡大率 = 1.0f;
context.相対X座標 = 0;
context.相対Y座標 = 0;
context.透明度0to1 = 1.0f;
}
else
{
// (A-c) 200~300
context.X方向拡大率 = 1.0f - ( ( context.進行カウンタ.現在値 - 200 ) / 100.0f );
context.Y方向拡大率 = 1.0f - ( ( context.進行カウンタ.現在値 - 200 ) / 100.0f );
context.相対X座標 = 0;
context.相対Y座標 = 0;
context.透明度0to1 = 1.0f;
}
//-----------------
#endregion
}
}
//----------------
#endregion
#region " 描画 "
//----------------
foreach( 表示レーン種別 lane in Enum.GetValues( typeof( 表示レーン種別 ) ) )
{
var context = this._表示レーンto進行描画コンテキスト[ lane ];
if( context.進行カウンタ.停止中である )
continue; // カウンタが停止中 → このレーンについては何もしない。
var 判定文字列の画像 = this._ヒットランク画像[ context.ヒットランク種別 ];
if( 判定文字列の画像.生成失敗 )
return;
var 判定文字列の左上端位置 =
new Vector2( context.相対X座標, context.相対Y座標 )
+ new Vector2( レーンフレームの左端 + レーンフレーム.レーンto横中央相対位置[ lane ], this._表示レーンtoレーン表示縦中央位置[ lane ] )
+ new Vector2(
-( ( 判定文字列の画像.サイズ.Width * context.X方向拡大率 ) / 2f ),
-( ( 判定文字列の画像.サイズ.Height * context.Y方向拡大率 ) / 2f ) );
判定文字列の画像?.描画する(
gd,
左位置: 判定文字列の左上端位置.X,
上位置: 判定文字列の左上端位置.Y,
不透明度0to1: context.透明度0to1,
X方向拡大率: context.X方向拡大率,
Y方向拡大率: context.Y方向拡大率 );
}
//----------------
#endregion
}
///
/// ヒット判定レーンには、それぞれに1つずつの進行描画コンテキストを用意する。
///
private class 進行描画コンテキスト
{
///
/// ヒット判定文字列のアニメ進行用カウンタ。
/// このカウンタが動作中のときのみ、ヒット判定文字列が描画される。
///
public Counter 進行カウンタ;
///
/// 現在表示中のヒット判定種別。
/// 進行カウンタが動作中のときのみ有効。
///
public ヒットランク種別 ヒットランク種別;
public bool 判定対象である;
public float 中央Y位置;
public float X方向拡大率;
public float Y方向拡大率;
public float 相対X座標;
public float 相対Y座標;
public float 透明度0to1;
public 進行描画コンテキスト()
{
this.初期化する();
}
public void 初期化する()
{
this.進行カウンタ = new Counter();
this.ヒットランク種別 = ヒットランク種別.AUTO;
this.判定対象である = true;
this.中央Y位置 = 0.0f;
this.X方向拡大率 = 1.0f;
this.Y方向拡大率 = 1.0f;
this.相対X座標 = 0.0f;
this.相対Y座標 = 0.0f;
this.透明度0to1 = 1.0f;
}
}
private Dictionary<表示レーン種別, 進行描画コンテキスト> _表示レーンto進行描画コンテキスト = null;
private readonly Dictionary<ヒットランク種別, 画像> _ヒットランク画像 = new Dictionary<ヒットランク種別, 画像>() {
{ ヒットランク種別.PERFECT, new 画像( @"$(System)images\Judge Perfect.png" ) },
{ ヒットランク種別.GREAT, new 画像( @"$(System)images\Judge Great.png" ) },
{ ヒットランク種別.GOOD, new 画像( @"$(System)images\Judge Good.png" ) },
{ ヒットランク種別.POOR, new 画像( @"$(System)images\Judge Poor.png" ) },
{ ヒットランク種別.MISS, new 画像( @"$(System)images\Judge Miss.png" ) },
{ ヒットランク種別.AUTO, new 画像( @"$(System)images\Judge Auto.png" ) },
};
private readonly Dictionary<表示レーン種別, float> _表示レーンtoレーン表示縦中央位置 = new Dictionary<表示レーン種別, float>() {
{ 表示レーン種別.Unknown, 0f },
{ 表示レーン種別.LeftCrash, 469f },
{ 表示レーン種別.HiHat, 562f },
{ 表示レーン種別.Snare, 641f },
{ 表示レーン種別.Tom1, 495f },
{ 表示レーン種別.Bass, 716f },
{ 表示レーン種別.Tom2, 558f },
{ 表示レーン種別.Tom3, 798f },
{ 表示レーン種別.RightCrash, 633f },
};
}
}