OSDN Git Service

"進行" を "高速進行" に改名。
[strokestylet/CsWin10Desktop3.git] / StrokeStyleT / ステージ / 演奏 / ヒットランク.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using System.Linq;
5 using SharpDX;
6 using FDK;
7 using FDK.メディア;
8 using FDK.カウンタ;
9 using SSTFormat.v2;
10
11 namespace SST.ステージ.演奏
12 {
13         class ヒットランク : Activity
14         {
15                 public ヒットランク()
16                 {
17                         // すべてのヒットランク画像を子リストに追加。
18                         foreach( var kvp in this._ヒットランク画像 )
19                                 this.子リスト.Add( kvp.Value );
20                 }
21
22                 public void 表示開始( 表示レーン種別 laneType, ヒットランク種別 hitRankType )
23                 {
24                         lock( this._スレッド間同期 )
25                         {
26                                 if( laneType == 表示レーン種別.Unknown )
27                                         return;
28
29                                 // レーンに対応する進行描画コンテキストを更新し、表示を開始するためのパラメータを設定する。
30                                 if( this._表示レーンto進行描画コンテキスト.ContainsKey( laneType ) ) // すでにあったら、
31                                         this._表示レーンto進行描画コンテキスト.Remove( laneType );       // 削除してから、
32
33                                 this._表示レーンto進行描画コンテキスト.Add(                                                                // 追加。
34                                         laneType,
35                                         new 進行描画コンテキスト() {
36                                                 ヒットランク種別 = hitRankType,
37                                                 進行カウンタ = new FDK.カウンタ.Counter( 最初の値: 0, 最後の値: 300, 値をひとつ増加させるのにかける時間ms: 1 ),    // カウント開始(=表示開始)
38                                                 X方向拡大率 = 1f,
39                                                 Y方向拡大率 = 1f,
40                                                 相対X座標 = 0,
41                                                 相対Y座標 = 0,
42                                                 透明度0to1 = 1f,
43                                         } );
44                         }
45                 }
46
47                 public void 表示開始( チップ種別 chipType, ヒットランク種別 hitRankType )
48                 {
49                         lock( this._スレッド間同期 )
50                         {
51                                 var laneType = App.ユーザ管理.選択されているユーザ.オプション設定.ドラムとチップと入力の対応表[ chipType ].表示レーン種別;
52
53                                 if( laneType != 表示レーン種別.Unknown )
54                                         this.表示開始( laneType, hitRankType );
55                         }
56                 }
57
58                 protected override void On活性化( グラフィックデバイス gd )
59                 {
60                         // すべての表示レーンについて、進行描画コンテキストを生成する。
61                         this._表示レーンto進行描画コンテキスト = new Dictionary<表示レーン種別, 進行描画コンテキスト>();
62                         foreach( 表示レーン種別 laneType in Enum.GetValues(typeof( 表示レーン種別 ) ) )
63                                 this._表示レーンto進行描画コンテキスト.Add( laneType, new 進行描画コンテキスト() );
64                 }
65
66                 protected override void On非活性化( グラフィックデバイス gd )
67                 {
68                         this._表示レーンto進行描画コンテキスト.Clear();
69                 }
70
71                 public void 進行する()
72                 {
73                         lock( this._スレッド間同期 )
74                         {
75                                 foreach( 表示レーン種別 lane in Enum.GetValues( typeof( 表示レーン種別 ) ) )
76                                 {
77                                         var context = this._表示レーンto進行描画コンテキスト[ lane ];
78
79                                         if( context.進行カウンタ.停止中である )
80                                                 continue;   // カウンタが停止中 → このレーンについては何もしない。
81
82                                         if( context.進行カウンタ.終了値に達した )
83                                         {
84                                                 #region " 進行カウンタが終了値に達したら停止 → 表示完了。"
85                                                 //----------------
86                                                 context.進行カウンタ.一時停止する();
87                                                 continue;
88                                                 //----------------
89                                                 #endregion
90                                         }
91
92                                         if( context.ヒットランク種別 != ヒットランク種別.MISS )
93                                         {
94                                                 #region " (A) Perfect, Great, Good, Poor, Auto のアニメーション進行。"
95                                                 //-----------------
96                                                 if( context.進行カウンタ.現在値 < 50 )
97                                                 {
98                                                         // (B-a) 0~49
99                                                         context.X方向拡大率 = 1.0f + ( 1.0f * ( 1.0f - ( context.進行カウンタ.現在値 / 50.0f ) ) );
100                                                         context.Y方向拡大率 = context.進行カウンタ.現在値 / 50.0f;
101                                                         context.相対X座標 = 0;
102                                                         context.相対Y座標 = 0;
103                                                         context.透明度0to1 = 1.0f;
104                                                 }
105                                                 else if( context.進行カウンタ.現在値 < 130 )
106                                                 {
107                                                         // (B-b) 50~129
108                                                         context.X方向拡大率 = 1.0f;
109                                                         context.Y方向拡大率 = 1.0f;
110                                                         context.相対X座標 = 0;
111                                                         context.相対Y座標 = ( ( context.進行カウンタ.現在値 % 6 ) == 0 ) ? ( App.乱数.Next( 6 ) - 3 ) : context.相対Y座標;
112                                                         context.透明度0to1 = 1.0f;
113                                                 }
114                                                 else if( context.進行カウンタ.現在値 < 240 )
115                                                 {
116                                                         // (B-c) 130~239
117                                                         context.X方向拡大率 = 1.0f;
118                                                         context.Y方向拡大率 = 1.0f;
119                                                         context.相対X座標 = 0;
120                                                         context.相対Y座標 = 0;
121                                                         context.透明度0to1 = 1.0f;
122                                                 }
123                                                 else
124                                                 {
125                                                         // (B-d) 240~300
126                                                         context.X方向拡大率 = 1.0f;
127                                                         context.Y方向拡大率 = 1.0f - ( ( 1.0f * ( context.進行カウンタ.現在値 - 240 ) ) / 60.0f );
128                                                         context.相対X座標 = 0;
129                                                         context.相対Y座標 = 0;
130                                                         context.透明度0to1 = 1.0f;
131                                                 }
132                                                 //-----------------
133                                                 #endregion
134                                         }
135                                         else
136                                         {
137                                                 #region " (B) Miss のアニメーション進行だけ他とは違ってたり。"
138                                                 //-----------------
139                                                 if( context.進行カウンタ.現在値 < 50 )
140                                                 {
141                                                         // (A-a) 0~49
142                                                         context.X方向拡大率 = 1.0f;
143                                                         context.Y方向拡大率 = context.進行カウンタ.現在値 / 50.0f;
144                                                         context.相対X座標 = 0;
145                                                         context.相対Y座標 = 0;
146                                                         context.透明度0to1 = 1.0f;
147                                                 }
148                                                 else if( context.進行カウンタ.現在値 < 200 )
149                                                 {
150                                                         // (A-b) 50~199
151                                                         context.X方向拡大率 = 1.0f;
152                                                         context.Y方向拡大率 = 1.0f;
153                                                         context.相対X座標 = 0;
154                                                         context.相対Y座標 = 0;
155                                                         context.透明度0to1 = 1.0f;
156                                                 }
157                                                 else
158                                                 {
159                                                         // (A-c) 200~300
160                                                         context.X方向拡大率 = 1.0f - ( ( context.進行カウンタ.現在値 - 200 ) / 100.0f );
161                                                         context.Y方向拡大率 = 1.0f - ( ( context.進行カウンタ.現在値 - 200 ) / 100.0f );
162                                                         context.相対X座標 = 0;
163                                                         context.相対Y座標 = 0;
164                                                         context.透明度0to1 = 1.0f;
165                                                 }
166                                                 //-----------------
167                                                 #endregion
168                                         }
169
170                                 }
171                         }
172                 }
173
174                 public void 描画する( グラフィックデバイス gd, float レーンフレームの左端 )
175                 {
176                         lock( this._スレッド間同期 )
177                         {
178                                 foreach( 表示レーン種別 lane in Enum.GetValues( typeof( 表示レーン種別 ) ) )
179                                 {
180                                         var context = this._表示レーンto進行描画コンテキスト[ lane ];
181
182                                         if( context.進行カウンタ.停止中である )
183                                                 continue;   // カウンタが停止中 → このレーンについては何もしない。
184
185                                         var 判定文字列の画像 = this._ヒットランク画像[ context.ヒットランク種別 ];
186                                         if( 判定文字列の画像.生成失敗 )
187                                                 return;
188
189                                         var 判定文字列の左上端位置 =
190                                                 new Vector2( context.相対X座標, context.相対Y座標 )
191                                                 + new Vector2( レーンフレームの左端 + レーンフレーム.レーンto横中央相対位置[ lane ], this._表示レーンtoレーン表示縦中央位置[ lane ] )
192                                                 + new Vector2(
193                                                         -( ( 判定文字列の画像.サイズ.Width * context.X方向拡大率 ) / 2f ),
194                                                         -( ( 判定文字列の画像.サイズ.Height * context.Y方向拡大率 ) / 2f ) );
195
196                                         判定文字列の画像?.描画する(
197                                                 gd,
198                                                 左位置: 判定文字列の左上端位置.X,
199                                                 上位置: 判定文字列の左上端位置.Y,
200                                                 不透明度0to1: context.透明度0to1,
201                                                 X方向拡大率: context.X方向拡大率,
202                                                 Y方向拡大率: context.Y方向拡大率 );
203                                 }
204                         }
205                 }
206
207
208                 /// <summary>
209                 ///             ヒット判定レーンには、それぞれに1つずつの進行描画コンテキストを用意する。
210                 /// </summary>
211                 private class 進行描画コンテキスト
212                 {
213                         /// <summary>
214                         ///             ヒット判定文字列のアニメ進行用カウンタ。
215                         ///             このカウンタが動作中のときのみ、ヒット判定文字列が描画される。
216                         /// </summary>
217                         public Counter 進行カウンタ;
218
219                         /// <summary>
220                         ///             現在表示中のヒット判定種別。
221                         ///             進行カウンタが動作中のときのみ有効。
222                         /// </summary>
223                         public ヒットランク種別 ヒットランク種別;
224
225                         public bool 判定対象である;
226                         public float 中央Y位置;
227
228                         public float X方向拡大率;
229                         public float Y方向拡大率;
230                         public float 相対X座標;
231                         public float 相対Y座標;
232                         public float 透明度0to1;
233
234                         public 進行描画コンテキスト()
235                         {
236                                 this.初期化する();
237                         }
238
239                         public void 初期化する()
240                         {
241                                 this.進行カウンタ = new Counter();
242                                 this.ヒットランク種別 = ヒットランク種別.AUTO;
243
244                                 this.判定対象である = true;
245                                 this.中央Y位置 = 0.0f;
246
247                                 this.X方向拡大率 = 1.0f;
248                                 this.Y方向拡大率 = 1.0f;
249                                 this.相対X座標 = 0.0f;
250                                 this.相対Y座標 = 0.0f;
251                                 this.透明度0to1 = 1.0f;
252                         }
253                 }
254
255                 private Dictionary<表示レーン種別, 進行描画コンテキスト> _表示レーンto進行描画コンテキスト = null;
256
257                 private readonly Dictionary<ヒットランク種別, 画像> _ヒットランク画像 = new Dictionary<ヒットランク種別, 画像>() {
258                         { ヒットランク種別.PERFECT, new 画像( @"$(System)images\Judge Perfect.png" ) },
259                         { ヒットランク種別.GREAT, new 画像( @"$(System)images\Judge Great.png" ) },
260                         { ヒットランク種別.GOOD, new 画像( @"$(System)images\Judge Good.png" ) },
261                         { ヒットランク種別.POOR, new 画像( @"$(System)images\Judge Poor.png" ) },
262                         { ヒットランク種別.MISS, new 画像( @"$(System)images\Judge Miss.png" ) },
263                         { ヒットランク種別.AUTO, new 画像( @"$(System)images\Judge Auto.png" ) },
264                 };
265
266                 private readonly Dictionary<表示レーン種別, float> _表示レーンtoレーン表示縦中央位置 = new Dictionary<表示レーン種別, float>() {
267                         { 表示レーン種別.Unknown, 0f },
268                         { 表示レーン種別.LeftCrash, 469f },
269                         { 表示レーン種別.HiHat, 562f },
270                         { 表示レーン種別.Snare, 641f },
271                         { 表示レーン種別.Tom1, 495f },
272                         { 表示レーン種別.Bass, 716f },
273                         { 表示レーン種別.Tom2, 558f },
274                         { 表示レーン種別.Tom3, 798f },
275                         { 表示レーン種別.RightCrash, 633f },
276                 };
277
278                 private readonly object _スレッド間同期 = new object();
279         }
280 }