using( Log.Block( FDKUtilities.現在のメソッド名 ) )
{
this._活性化した直後である = true;
- this._演奏開始時刻sec = 0.0;
this._背景動画開始済み = false;
this._現在進行描画中の譜面スクロール速度の倍率 = App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率;
this._描画開始チップ番号 = -1;
}
}
- public override void 進行する()
+ public override void é«\98é\80\9fé\80²è¡\8cã\81\99ã\82\8b()
{
Debug.Assert( this.活性化している );
double 演奏開始位置の先頭からの時間sec = 0.0;
// 演奏開始時刻の設定(1)
- this._演奏開始時刻sec = App.サウンドデバイス.GetDevicePosition() - 演奏開始位置の先頭からの時間sec;
- Log.Info( $"演奏開始時刻(背景動画再生チェック前): {this._演奏開始時刻sec} sec" );
+ App.サウンドタイマ.リセットする( 演奏開始位置の先頭からの時間sec );
+ Log.Info( $"演奏開始時刻(背景動画再生チェック前): {App.サウンドタイマ.現在時刻sec} sec" );
// 演奏開始時刻の設定(2) ビュアーメッセージがある場合、開始時刻を修正する。
var msg = App.最後に取得したビュアーメッセージ;
this._再生中の時刻なら動画とBGMを再生開始する( 演奏開始位置の先頭からの時間sec );
// 演奏開始時刻の設定(3) 動画とBGMが再生された場合、ここに到達するまでに多少の遅延が生じているので、ここで演奏開始時刻を再取得しておく。
- this._演奏開始時刻sec = App.サウンドデバイス.GetDevicePosition() - 演奏開始位置の先頭からの時間sec;
- Log.Info( $"演奏開始時刻(背景動画再生チェック後): {this._演奏開始時刻sec} sec" );
+ App.サウンドタイマ.リセットする( 演奏開始位置の先頭からの時間sec );
+ Log.Info( $"演奏開始時刻(背景動画再生チェック後): {App.サウンドタイマ.現在時刻sec} sec" );
//----------------
#endregion
}
this._FPS.FPSをカウントしプロパティを更新する();
- #region " 譜面スクロール速度が変化している → 追い付き進行 "
- //----------------
- {
- double 倍率 = this._現在進行描画中の譜面スクロール速度の倍率;
-
- if( 倍率 < App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 )
- {
- if( 0 > this._スクロール倍率追い付き用_最後の値 )
- {
- this._スクロール倍率追い付き用カウンタ = new LoopCounter( 0, 1000, 10 ); // 0→100; 全部で10×1000 = 10000ms = 10sec あれば十分だろう
- this._スクロール倍率追い付き用_最後の値 = 0;
- }
- else
- {
- while( this._スクロール倍率追い付き用_最後の値 < this._スクロール倍率追い付き用カウンタ.現在値 )
- {
- 倍率 += 0.025;
- this._スクロール倍率追い付き用_最後の値++;
- }
-
- this._現在進行描画中の譜面スクロール速度の倍率 =
- Math.Min( 倍率, App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 );
- }
- }
- else if( 倍率 > App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 )
- {
- if( 0 > this._スクロール倍率追い付き用_最後の値 )
- {
- this._スクロール倍率追い付き用カウンタ = new LoopCounter( 0, 1000, 10 ); // 0→100; 全部で10×1000 = 10000ms = 10sec あれば十分だろう
- this._スクロール倍率追い付き用_最後の値 = 0;
- }
- else
- {
- while( this._スクロール倍率追い付き用_最後の値 < this._スクロール倍率追い付き用カウンタ.現在値 )
- {
- 倍率 -= 0.025;
- this._スクロール倍率追い付き用_最後の値++;
- }
-
- this._現在進行描画中の譜面スクロール速度の倍率 =
- Math.Max( 倍率, App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 );
- }
- }
- else
- {
- this._スクロール倍率追い付き用_最後の値 = -1;
- this._スクロール倍率追い付き用カウンタ = null;
- }
- }
- //----------------
- #endregion
-
#region " 背景動画が再生されているのにBGMがまだ再生されていないなら、すぐに再生を開始する。"
//----------------
if( this._背景動画開始済み && !( this._BGM再生開始済み ) )
//----------------
#endregion
- this._レーンフレーム.進行する();
- this._コンボ.進行する();
- this._ヒットランク.進行する();
- this._ドラムセット.進行する();
- this._回転羽.進行する();
-
double 現在の演奏時刻sec = this._演奏開始からの経過時間secを返す();
+ // 自動演奏
+
#region " 自動ヒット処理。"
//----------------
- this._描画範囲のチップに処理を適用する( 現在の演奏時刻sec, ( chip, index, ヒット判定バーとの時間sec, ヒット判定バーとの距離 ) => {
+ this._描画範囲のチップに処理を適用する( 現在の演奏時刻sec, ( chip, index, ヒット判定バーと描画との時間sec, ヒット判定バーと発声との時間sec, ヒット判定バーとの距離 ) => {
var オプション設定 = App.ユーザ管理.選択されているユーザ.オプション設定;
var 対応表 = オプション設定.ドラムとチップと入力の対応表[ chip.チップ種別 ];
var AutoPlay = オプション設定.AutoPlay[ 対応表.AutoPlay種別 ];
bool チップはヒット済みである = chip.ヒット済みである;
- bool チップはMISSエリアに達している = ( ヒット判定バーとの時間sec > オプション設定.最大ヒット距離sec[ ヒットランク種別.POOR ] );
- bool チップはヒット判定バーを通過した = ( 0 <= ヒット判定バーとの距離 );
+ bool チップはMISSエリアに達している = ( ヒット判定バーと描画との時間sec > オプション設定.最大ヒット距離sec[ ヒットランク種別.POOR ] );
+ bool チップは描画についてヒット判定バーを通過した = ( 0 <= ヒット判定バーと描画との時間sec );
+ bool チップは発声についてヒット判定バーを通過した = ( 0 <= ヒット判定バーと発声との時間sec );
if( チップはヒット済みである )
{
// MISS判定。
if( AutoPlay && 対応表.AutoPlayON.MISS判定 )
{
- this._チップのヒット処理を行う( chip, ヒットランク種別.MISS, 対応表.AutoPlayON.自動ヒット時処理 );
+ this._チップのヒット処理を行う( chip, ヒットランク種別.MISS, 対応表.AutoPlayON.自動ヒット時処理, ヒット判定バーと発声との時間sec );
return;
}
else if( !AutoPlay && 対応表.AutoPlayOFF.MISS判定 )
{
- this._チップのヒット処理を行う( chip, ヒットランク種別.MISS, 対応表.AutoPlayOFF.ユーザヒット時処理 );
+ this._チップのヒット処理を行う( chip, ヒットランク種別.MISS, 対応表.AutoPlayOFF.ユーザヒット時処理, ヒット判定バーと発声との時間sec );
return;
}
else
}
}
- if( チップはヒット判定バーを通過した )
+ if( チップは発声についてヒット判定バーを通過した )
+ {
+ // 自動ヒット判定。
+ if( ( AutoPlay && 対応表.AutoPlayON.自動ヒット && 対応表.AutoPlayON.自動ヒット時処理.再生 ) ||
+ ( !AutoPlay && 対応表.AutoPlayOFF.自動ヒット && 対応表.AutoPlayOFF.自動ヒット時処理.再生 ) )
+ {
+ this._チップの発声を行う( chip, ヒット判定バーと発声との時間sec );
+ }
+ }
+
+ if( チップは描画についてヒット判定バーを通過した )
{
// 自動ヒット判定。
if( AutoPlay && 対応表.AutoPlayON.自動ヒット )
{
- this._チップのヒット処理を行う( chip, ヒットランク種別.AUTO, 対応表.AutoPlayON.自動ヒット時処理 );
+ this._チップのヒット処理を行う( chip, ヒットランク種別.AUTO, 対応表.AutoPlayON.自動ヒット時処理, ヒット判定バーと発声との時間sec );
return;
}
else if( !AutoPlay && 対応表.AutoPlayOFF.自動ヒット )
{
- this._チップのヒット処理を行う( chip, ヒットランク種別.AUTO, 対応表.AutoPlayOFF.自動ヒット時処理 );
+ this._チップのヒット処理を行う( chip, ヒットランク種別.AUTO, 対応表.AutoPlayOFF.自動ヒット時処理, ヒット判定バーと発声との時間sec );
return;
}
else
//----------------
#endregion
- // 入力。
+ // 入力(1) 手動演奏
App.入力管理.すべての入力デバイスをポーリングする( 入力履歴を記録する: false );
+ #region " ユーザヒット処理。"
+ //----------------
+ {
+ var オプション設定 = App.ユーザ管理.選択されているユーザ.オプション設定;
+
+ #region " ヒットしてようがしてまいが起こすアクション(空打ち処理)。 "
+ //----------------
+ foreach( var 入力 in App.入力管理.ポーリング結果 )
+ {
+ if( 入力.InputEvent.離された )
+ continue; // 押下イベントじゃないなら無視。
+
+ this._ドラムセット.ヒットアニメ開始( 入力.Type, オプション設定.表示レーンの左右 );
+
+ var カラム = オプション設定.ドラムとチップと入力の対応表.対応表.Where( ( kvp ) => ( kvp.Value.ドラム入力種別 == 入力.Type ) ); // カラムは struct なので FirstOrDefault() は使わない。
+ if( 0 < カラム.Count() )
+ this._レーンフレーム.フラッシュ開始( カラム.First().Value.表示レーン種別 );
+ }
+ //----------------
+ #endregion
+
+ var 処理済み入力 = new List<ドラム入力イベント>(); // ヒット処理が終わった入力は、二重処理しないよう、この中に追加しておく。
+
+ this._描画範囲のチップに処理を適用する( 現在の演奏時刻sec, ( chip, index, ヒット判定バーと描画との時間sec, ヒット判定バーと発声との時間sec, ヒット判定バーとの距離 ) => {
+
+ #region " ヒット判定 "
+ //----------------
+ if( chip.ヒット済みである )
+ return;
+
+ var チップの対応表 = オプション設定.ドラムとチップと入力の対応表[ chip.チップ種別 ];
+
+ if( オプション設定.AutoPlay[ チップの対応表.AutoPlay種別 ] )
+ return; // チップが AutoPlay ON である。
+
+ if( !( チップの対応表.AutoPlayOFF.ユーザヒット ) )
+ return; // このチップは、AutoPlay OFF 時でもユーザヒットの対象ではない。
+
+ double ヒット判定バーとの時間の絶対値sec = Math.Abs( ヒット判定バーと描画との時間sec );
+
+ bool チップはMISSエリアに達している = ( ヒット判定バーと描画との時間sec > オプション設定.最大ヒット距離sec[ ヒットランク種別.POOR ] );
+ if( !( ヒット判定バーと描画との時間sec >= -( オプション設定.最大ヒット距離sec[ ヒットランク種別.POOR ] ) && !チップはMISSエリアに達している ) )
+ return; // チップはヒット可能エリアにある。
+
+ var ヒット入力 = App.入力管理.ポーリング結果.FirstOrDefault( ( 入力 ) => {
+ #region " chip にヒットする入力があれば true を返す。"
+ //----------------
+ if( !( 入力.InputEvent.押された ) )
+ return false; // 押下入力じゃない。
+
+ if( 処理済み入力.Contains( 入力 ) )
+ return false; // すでに今回のターンで処理済み(=処理済み入力リストに追加済み)。
+
+ // chip がシンバルフリーの対象なら、chip に直接対応する入力の他にも、ヒット判定すべき入力がある。
+ if( チップの対応表.シンバルフリーの対象 && オプション設定.シンバルフリー )
+ {
+ // この入力に対応するカラムのうち、
+ var カラムs = オプション設定.ドラムとチップと入力の対応表.対応表.Where( ( kvp ) => ( kvp.Value.ドラム入力種別 == 入力.Type ) );
+ foreach( var カラム in カラムs )
+ {
+ // シンバルフリーなチップがあるなら true。
+ if( カラム.Value.シンバルフリーの対象 )
+ return true;
+ }
+ // まったくなかったら false。
+ return false;
+ }
+
+ // chip に対応する入力なら true。
+ return ( チップの対応表.ドラム入力種別 == 入力.Type );
+ //----------------
+ #endregion
+ } );
+
+ if( null == ヒット入力 )
+ return;
+ //----------------
+ #endregion
+
+ 処理済み入力.Add( ヒット入力 );
+
+ #region " ヒットランクを判定する。"
+ //----------------
+ var ヒットランク = ヒットランク種別.POOR;
+
+ if( ヒット判定バーとの時間の絶対値sec <= オプション設定.最大ヒット距離sec[ ヒットランク種別.PERFECT ] )
+ {
+ ヒットランク = ヒットランク種別.PERFECT;
+ }
+ else if( ヒット判定バーとの時間の絶対値sec <= オプション設定.最大ヒット距離sec[ ヒットランク種別.GREAT ] )
+ {
+ ヒットランク = ヒットランク種別.GREAT;
+ }
+ else if( ヒット判定バーとの時間の絶対値sec <= オプション設定.最大ヒット距離sec[ ヒットランク種別.GOOD ] )
+ {
+ ヒットランク = ヒットランク種別.GOOD;
+ }
+ //----------------
+ #endregion
+
+ this._チップのヒット処理を行う( chip, ヒットランク, チップの対応表.AutoPlayOFF.ユーザヒット時処理, ヒット判定バーと発声との時間sec );
+
+ } );
+ }
+ //----------------
+ #endregion
+
+ // 入力(2) アプリ操作
+
if( App.入力管理.キーボードデバイス.キーが押された( 0, Key.Escape ) )
{
#region " ESC → ステージキャンセル "
//----------------
#endregion
}
+ }
+ //----------------
+ #endregion
+ break;
+ }
+ }
- #region " ユーザヒット処理。"
- //----------------
- foreach( var 入力 in App.入力管理.ポーリング結果 )
- {
- if( 入力.InputEvent.離された )
- continue; // 押下イベントじゃないなら無視。
-
- this._ドラムセット.ヒットアニメ開始( 入力.Type, App.ユーザ管理.選択されているユーザ.オプション設定.表示レーンの左右 );
- }
-
- var 処理済み入力 = new List<ドラム入力イベント>(); // ヒット処理が終わった入力は、二重処理しないよう、この中に追加しておく。
-
- this._描画範囲のチップに処理を適用する( 現在の演奏時刻sec, ( chip, index, ヒット判定バーとの時間sec, ヒット判定バーとの距離 ) => {
-
- var オプション設定 = App.ユーザ管理.選択されているユーザ.オプション設定;
- var 対応表 = オプション設定.ドラムとチップと入力の対応表[ chip.チップ種別 ];
- bool AutoPlay = オプション設定.AutoPlay[ 対応表.AutoPlay種別 ];
- double ヒット判定バーとの時間の絶対値sec = Math.Abs( ヒット判定バーとの時間sec );
- bool チップはヒット済みである = chip.ヒット済みである;
- bool チップはMISSエリアに達している = ( ヒット判定バーとの時間sec > オプション設定.最大ヒット距離sec[ ヒットランク種別.POOR ] );
- bool チップはヒット可能エリアにある = ( ヒット判定バーとの時間sec >= -( オプション設定.最大ヒット距離sec[ ヒットランク種別.POOR ] ) && !チップはMISSエリアに達している );
-
- if( AutoPlay || チップはヒット済みである || !( 対応表.AutoPlayOFF.ユーザヒット ) || !( チップはヒット可能エリアにある ) )
- return;
-
- // チップにヒットする入力を探す。
- var ヒット入力 = App.入力管理.ポーリング結果.FirstOrDefault( ( 入力 ) => {
+ public override void 進行描画する( グラフィックデバイス gd )
+ {
+ Debug.Assert( this.活性化している );
+ Debug.Assert( null != gd );
- if( !( 入力.InputEvent.押された ) )
- return false; // 押下入力じゃない。
+ switch( this.現在のフェーズ )
+ {
+ case フェーズ.演奏中:
+ if( this._活性化した直後である )
+ break; // 進行処理がまだ行われていない。
- if( 処理済み入力.Contains( 入力 ) )
- return false; // すでに今回のターンで処理済み(=処理済み入力リストに追加済み)。
+ #region " 譜面スクロール速度が変化している → 追い付き進行 "
+ //----------------
+ {
+ double 倍率 = this._現在進行描画中の譜面スクロール速度の倍率;
- if( 対応表.シンバルフリーの対象 && オプション設定.シンバルフリー )
- {
- // (A) シンバルフリーの対象チップであり、かつシンバルフリーが ON である場合
- var 入力の対応表 = オプション設定.ドラムとチップと入力の対応表.対応表.FirstOrDefault( ( kvp ) => ( kvp.Value.ドラム入力種別 == 入力.Type ) ).Value; // 見つからなきゃバグだ
- if( !( 入力の対応表.シンバルフリーの対象 ) )
- return false; // この入力はシンバルフリーの対象ではない。
- }
- else
+ if( 倍率 < App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 )
+ {
+ if( 0 > this._スクロール倍率追い付き用_最後の値 )
+ {
+ this._スクロール倍率追い付き用カウンタ = new LoopCounter( 0, 1000, 10 ); // 0→100; 全部で10×1000 = 10000ms = 10sec あれば十分だろう
+ this._スクロール倍率追い付き用_最後の値 = 0;
+ }
+ else
+ {
+ while( this._スクロール倍率追い付き用_最後の値 < this._スクロール倍率追い付き用カウンタ.現在値 )
{
- // (B) シンバルフリーの対象ではないチップ、またはシンバルフリーが OFF である場合
- if( 対応表.ドラム入力種別 != 入力.Type )
- return false; // チップに対応している入力じゃない。
+ 倍率 += 0.025;
+ this._スクロール倍率追い付き用_最後の値++;
}
- return true; // この 入力 はこの chip にヒットしている。
- } );
-
- if( null == ヒット入力 )
- return;
-
- 処理済み入力.Add( ヒット入力 );
-
- // ヒットランクを判定する。
-
- var ヒットランク = ヒットランク種別.POOR;
-
- if( ヒット判定バーとの時間の絶対値sec <= オプション設定.最大ヒット距離sec[ ヒットランク種別.PERFECT ] )
- {
- ヒットランク = ヒットランク種別.PERFECT;
+ this._現在進行描画中の譜面スクロール速度の倍率 =
+ Math.Min( 倍率, App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 );
}
- else if( ヒット判定バーとの時間の絶対値sec <= オプション設定.最大ヒット距離sec[ ヒットランク種別.GREAT ] )
+ }
+ else if( 倍率 > App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 )
+ {
+ if( 0 > this._スクロール倍率追い付き用_最後の値 )
{
- ヒットランク = ヒットランク種別.GREAT;
+ this._スクロール倍率追い付き用カウンタ = new LoopCounter( 0, 1000, 10 ); // 0→100; 全部で10×1000 = 10000ms = 10sec あれば十分だろう
+ this._スクロール倍率追い付き用_最後の値 = 0;
}
- else if( ヒット判定バーとの時間の絶対値sec <= オプション設定.最大ヒット距離sec[ ヒットランク種別.GOOD ] )
+ else
{
- ヒットランク = ヒットランク種別.GOOD;
- }
-
- // ヒット処理。
-
- this._チップのヒット処理を行う( chip, ヒットランク, 対応表.AutoPlayOFF.ユーザヒット時処理 );
-
- } );
- //----------------
- #endregion
- }
- //----------------
- #endregion
- break;
-
- case フェーズ.クリア時フェードアウト:
- #region " *** "
- //----------------
- if( this._クリア時フェードアウト.開始されていない )
- {
- this._クリア時フェードアウト.開始する();
- }
- else
- {
- this._クリア時フェードアウト.進行する();
+ while( this._スクロール倍率追い付き用_最後の値 < this._スクロール倍率追い付き用カウンタ.現在値 )
+ {
+ 倍率 -= 0.025;
+ this._スクロール倍率追い付き用_最後の値++;
+ }
- if( this._クリア時フェードアウト.完了した )
+ this._現在進行描画中の譜面スクロール速度の倍率 =
+ Math.Max( 倍率, App.ユーザ管理.選択されているユーザ.オプション設定.譜面スクロール速度の倍率 );
+ }
+ }
+ else
{
- this.現在のフェーズ = フェーズ.クリア;
+ this._スクロール倍率追い付き用_最後の値 = -1;
+ this._スクロール倍率追い付き用カウンタ = null;
}
}
//----------------
#endregion
- break;
-
- case フェーズ.Failed:
- case フェーズ.クリア:
- case フェーズ.キャンセル:
- case フェーズ.ビュアーメッセージ待機:
- break;
- }
- }
-
- public override void 描画する( グラフィックデバイス gd )
- {
- Debug.Assert( this.活性化している );
- Debug.Assert( null != gd );
- switch( this.現在のフェーズ )
- {
- case フェーズ.演奏中:
- if( this._活性化した直後である )
- break; // 進行処理がまだ行われていない。
+ this._コンボ.進行描画する( gd );
+ this._回転羽.進行描画する( gd );
double 演奏時刻sec = this._演奏開始からの経過時間secを返す();
#endregion
this._ステージ台.描画する( gd, 0f, 0f );
- this._レーンフレーム.描画する( gd, レーンフレームの左端位置 );
- this._コンボ.描画する( gd );
- this._ヒットランク.描画する( gd, レーンフレームの左端位置 );
+ this._レーンフレーム.進行描画する( gd, レーンフレームの左端位置 );
+ this._コンボ.進行描画する( gd );
+ this._ヒットランク.進行描画する( gd, レーンフレームの左端位置 );
this._小節線拍線を描画する( gd, 演奏時刻sec );
this._ヒット判定バー.描画する( gd, 597f, ヒット判定バーの中央Y座標 - 43f );
- this._ドラムセット.描画する( gd );
+ this._ドラムセット.進行描画する( gd );
this._チップを描画する( gd, 演奏時刻sec );
- this._回転羽.描画する( gd );
+ this._回転羽.進行描画する( gd );
this._FPS.VPSをカウントする();
this._FPS.描画する( gd, 0f, 0f );
break;
case フェーズ.クリア時フェードアウト:
+ if( this._クリア時フェードアウト.開始されていない )
+ {
+ this._クリア時フェードアウト.開始する();
+ }
+ else
+ {
+ if( this._クリア時フェードアウト.完了した )
+ {
+ this.現在のフェーズ = フェーズ.クリア;
+ }
+ }
this._ステージ台.描画する( gd, 0f, 0f );
- this._レーンフレーム.描画する( gd, レーンフレームの左端位置 );
+ this._レーンフレーム.進行描画する( gd, レーンフレームの左端位置 );
this._ヒット判定バー.描画する( gd, 597f, ヒット判定バーの中央Y座標 - 43f );
- this._ドラムセット.描画する( gd );
- this._回転羽.描画する( gd );
- this._クリア時フェードアウト.描画する( gd, this._白パネル );
+ this._ドラムセット.進行描画する( gd );
+ this._回転羽.進行描画する( gd );
+ this._クリア時フェードアウト.進行描画する( gd, this._白パネル );
this._FPS.VPSをカウントする();
this._FPS.描画する( gd, 0f, 0f );
break;
}
- private double _演奏開始時刻sec = 0.0;
-
private double _現在進行描画中の譜面スクロール速度の倍率 = 1.0;
/// <summary>
private bool _活性化した直後である;
+
// 譜面描画。
/// <summary>
double 再生開始時刻sec = ( 時刻sec - 背景動画チップ.発声時刻sec );
this._背景動画?.再生を開始する( 再生開始時刻sec );
this._背景動画開始済み = true;
- this._BGM?.Play( 再生開始時刻sec );
+ this._BGM?.Play( 再生開始時刻sec - App.サウンドデバイス.遅延sec );
this._BGM再生開始済み = true;
Log.Info( $"背景動画の再生を開始しました。(再生開始時刻: {再生開始時刻sec} sec)" );
}
private double _演奏開始からの経過時間secを返す()
{
- return App.ã\82µã\82¦ã\83³ã\83\89ã\83\87ã\83\90ã\82¤ã\82¹.GetDevicePosition() - this._æ¼\94å¥\8fé\96\8bå§\8b時刻sec;
+ return App.ã\82µã\82¦ã\83³ã\83\89ã\82¿ã\82¤ã\83\9e.ç\8f¾å\9c¨時刻sec;
}
// 小節線・拍線 と チップ は描画階層(奥行き)が異なるので、別々のメソッドに分ける。
this._チップ画像.加算合成 = false;
- this._描画範囲のチップに処理を適用する( 現在の演奏時刻sec, ( chip, index, ヒット判定バーとの時間sec, ヒット判定バーとの距離 ) => {
+ this._描画範囲のチップに処理を適用する( 現在の演奏時刻sec, ( chip, index, ヒット判定バーと描画との時間sec, ヒット判定バーと発声との時間sec, ヒット判定バーとの距離 ) => {
if( chip.チップ種別 == チップ種別.小節線 )
{
this._チップ画像.加算合成 = false;
- this._描画範囲のチップに処理を適用する( 現在の演奏時刻sec, ( chip, index, ヒット判定バーとの時間sec, ヒット判定バーとの距離 ) => {
+ this._描画範囲のチップに処理を適用する( 現在の演奏時刻sec, ( chip, index, ヒット判定バーと描画との時間sec, ヒット判定バーと発声との時間sec, ヒット判定バーとの距離 ) => {
float 縦中央位置 = (float)( ヒット判定バーの中央Y座標 + ヒット判定バーとの距離 );
/// <see cref="_描画開始チップ番号"/> から画面上端にはみ出すまでの間の各チップに対して、指定された処理を適用する。
/// </summary>
/// <param name="適用する処理">引数は、順に、対象のチップ、チップ番号、ヒット判定バーとの時間sec、ヒット判定バーとの距離</param>
- private void _描画範囲のチップに処理を適用する( double 現在の演奏時刻sec, Action<チップ, int, double, double> 適用する処理 )
+ private void _描画範囲のチップに処理を適用する( double 現在の演奏時刻sec, Action<チップ, int, double, double, double> 適用する処理 )
{
var スコア = App.演奏スコア;
if( null == スコア )
var チップ = スコア.チップリスト[ i ];
// ヒット判定バーとチップの間の、時間 と 距離 を算出。→ いずれも、負数ならバー未達、0でバー直上、正数でバー通過。
- double ヒット判定バーとの時間sec = 現在の演奏時刻sec - チップ.描画時刻sec;
- double ヒット判定バーとの距離 = スコア.指定された時間secに対応する符号付きピクセル数を返す( this._現在進行描画中の譜面スクロール速度の倍率, ヒット判定バーとの時間sec );
+ double ヒット判定バーと描画との時間sec = 現在の演奏時刻sec - チップ.描画時刻sec;
+ double ヒット判定バーと発声との時間sec = 現在の演奏時刻sec - チップ.発声時刻sec;
+ double ヒット判定バーとの距離 = スコア.指定された時間secに対応する符号付きピクセル数を返す( this._現在進行描画中の譜面スクロール速度の倍率, ヒット判定バーと描画との時間sec );
// 終了判定。
bool チップは画面上端より上に出ている = ( ( ヒット判定バーの中央Y座標 + ヒット判定バーとの距離 ) < -40.0 ); // -40 はチップが隠れるであろう適当なマージン。
break;
// 処理実行。開始判定(描画開始チップ番号の更新)もこの中で。
- 適用する処理( チップ, i, ヒット判定バーとの時間sec, ヒット判定バーとの距離 );
+ 適用する処理( チップ, i, ヒット判定バーと描画との時間sec, ヒット判定バーと発声との時間sec, ヒット判定バーとの距離 );
}
}
- private void _チップのヒット処理を行う( チップ chip, ヒットランク種別 hitRankType, ドラムとチップと入力の対応表.Column.Columnヒット処理 ヒット処理表 )
+ private void _チップのヒット処理を行う( チップ chip, ヒットランク種別 hitRankType, ドラムとチップと入力の対応表.Column.Columnヒット処理 ヒット処理表, double ヒット判定バーと発声との時間sec )
{
chip.ヒット済みである = true;
if( ヒット処理表.再生 )
{
- #region " ã\83\81ã\83\83ã\83\97ã\82\92å\86\8dç\94\9fã\81\99ã\82\8b。"
+ #region " ã\83\81ã\83\83ã\83\97ã\81®ç\99ºå£°ã\82\92è¡\8cã\81\86。"
//----------------
- if( chip.チップ種別 == チップ種別.背景動画 )
- {
- // 背景動画の再生を開始する。
- this._背景動画?.再生を開始する();
- this._背景動画開始済み = true;
-
- // BGMの再生を開始する。
- this._BGM?.Play();
- this._BGM再生開始済み = true;
- }
- else
- {
- if( App.システム設定.Autoチップのドラム音を再生する )
- this._ドラムサウンド.発声する( chip.チップ種別, ( chip.音量 / (float) チップ.最大音量 ) );
- }
+ if( chip.発声されていない )
+ this._チップの発声を行う( chip, ヒット判定バーと発声との時間sec );
//----------------
#endregion
}
ヒット判定バーの中央Y座標 ) );
this._ドラムセット.ヒットアニメ開始( 対応表.ドラム入力種別, App.ユーザ管理.選択されているユーザ.オプション設定.表示レーンの左右 );
- this._レーンフレーム.フラッシュ開始( 対応表.表示レーン種別 );
+
+ if( hitRankType == ヒットランク種別.AUTO )
+ this._レーンフレーム.フラッシュ開始( 対応表.表示レーン種別 ); // レーンフラッシュは Auto 時のみ。
this._ヒットランク.表示開始( chip.チップ種別, hitRankType );
this.ヒットランク別ヒット回数[ hitRankType ]++;
#endregion
}
}
+
+ private void _チップの発声を行う( チップ chip, double 再生開始位置sec )
+ {
+ if( chip.発声済みである )
+ return;
+
+ chip.発声済みである = true;
+
+ if( chip.チップ種別 == チップ種別.背景動画 )
+ {
+ App.サウンドタイマ.一時停止する();
+
+ // 背景動画の再生を開始する。
+ this._背景動画?.再生を開始する();
+ this._背景動画開始済み = true;
+
+ // BGMの再生を開始する。
+ this._BGM?.Play( 再生開始位置sec );
+ this._BGM再生開始済み = true;
+
+ App.サウンドタイマ.再開する();
+ }
+ else
+ {
+ // BGM以外のサウンドについては、再生開始位置sec は反映せず、常に最初から再生する。
+ if( App.システム設定.Autoチップのドラム音を再生する )
+ this._ドラムサウンド.発声する( chip.チップ種別, ( chip.音量 / (float) チップ.最大音量 ) );
+ }
+ }
}
}