using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Drawing; using SlimDX; using FDK; namespace DTXMania { internal class CAct演奏Combo共通 : CActivity { public STDGBSValue dgbコンボ数; public class CComboStatus { //public CAct演奏Combo共通 act; public int n最高値 { get; private set; } public int n現在値 { get; private set; } public CAct演奏Combo共通.EMode e現在のモード = EMode.非表示中; public int nCOMBO値 = 0; public long nコンボが切れた時刻 = -1; public int nジャンプインデックス値 = 99999; public int n現在表示中のCOMBO値 = 0; public long n前回の時刻_ジャンプ用 = -1; public void IncrementCombo() { ++n現在値; if (n現在値 > n最高値) { n最高値 = n現在値; } nCOMBO値 = n現在値; } public void ResetCombo() { n現在値 = 0; } } private int[] nジャンプ差分値 = new int[180]; // private STDGBVALUE status; private CTexture tex; public enum EEvent { 非表示, 数値更新, 同一数値, ミス通知 } public enum EMode { 非表示中, 進行表示中, 残像表示中 } public CAct演奏Combo共通() { this.b活性化してない = true; // 180度分のジャンプY座標差分を取得。(0度: 0 → 90度:-15 → 180度: 0) for (int i = 0; i < 180; i++) { this.nジャンプ差分値[i] = (int)(-15.0 * Math.Sin((Math.PI * i) / 180.0) * Scale.Y); } } private void tコンボ表示(EPart inst, int nCombo値, int nジャンプインデックス) { int x, y; x = CDTXMania.Instance.ConfigIni.cdComboX[inst][CDTXMania.Instance.ConfigIni.eActiveInst]; y = CDTXMania.Instance.ConfigIni.cdComboY[inst][CDTXMania.Instance.ConfigIni.eActiveInst]; if (CDTXMania.Instance.ConfigIni.bReverse[inst]) { y = SampleFramework.GameWindowSize.Height - y - CDTXMania.Instance.Coordinates.ImgComboCombo.H - CDTXMania.Instance.Coordinates.ImgComboOneDigit.H; } if (tex != null) { tex.n透明度 = 0xff; } int[] n位の数 = new int[10]; // 表示は10桁もあれば足りるだろう //----------------- if (CDTXMania.Instance.ConfigIni.bDisplayCombo[inst] && nCombo値 > 0) { // n位の数[] の格納。(例:nCombo値=125 のとき n位の数 = { 5,2,1,0,0,0,0,0,0,0 }) int n = nCombo値; int n桁数 = 0; int n全桁の合計幅 = 0; while ((n > 0) && (n桁数 < 10)) { n位の数[n桁数] = n % 10; // 1の位を格納 n = (n - (n % 10)) / 10; // 右へシフト(例: 12345 → 1234 ) n全桁の合計幅 += CDTXMania.Instance.Coordinates.ImgComboOneDigit.W; n桁数++; } // "COMBO" の拡大率を設定 float f拡大率 = 1.0f; if (nジャンプインデックス >= 0 && nジャンプインデックス < 180) f拡大率 = 1.0f - (((float)this.nジャンプ差分値[nジャンプインデックス]) / 45.0f); // f拡大率 = 1.0 → 1.3333... → 1.0 if (this.tex != null) { this.tex.vc拡大縮小倍率 = new Vector3(f拡大率, f拡大率, 1.0f); } // "COMBO" 文字を表示 int cbx = x - ((int)((CDTXMania.Instance.Coordinates.ImgComboCombo.W * f拡大率) / 2.0f)); if (this.tex != null) this.tex.t2D描画(CDTXMania.Instance.Device, cbx, y + CDTXMania.Instance.Coordinates.ImgComboOneDigit.H, CDTXMania.Instance.Coordinates.ImgComboCombo); x = x + (n全桁の合計幅 / 2); // 1文字ずつ表示していく for (int i = 0; i < n桁数; i++) { f拡大率 = 1.0f; if (nジャンプインデックス >= 0 && nジャンプインデックス < 180) f拡大率 = 1.0f - (((float)this.nジャンプ差分値[nジャンプインデックス]) / 45f); // f拡大率 = 1.0 → 1.3333... → 1.0 if (this.tex != null) this.tex.vc拡大縮小倍率 = new Vector3(f拡大率, f拡大率, 1.0f); x -= CDTXMania.Instance.Coordinates.ImgComboOneDigit.W; if (this.tex != null) { this.tex.t2D描画( CDTXMania.Instance.Device, x - ((int)(((f拡大率 - 1.0f) * CDTXMania.Instance.Coordinates.ImgComboOneDigit.W) / 2.0f)), y - ((int)(((f拡大率 - 1.0f) * CDTXMania.Instance.Coordinates.ImgComboOneDigit.H) / 2.0f)), CDTXMania.Instance.Coordinates.ImgComboOneDigit.ApplyCounterXY(n位の数[i] % 4, n位の数[i] / 4, 0, 0)); } } } } // CActivity 実装 public override void On活性化() { this.dgbコンボ数 = new STDGBSValue(); for (EPart i = EPart.Drums; i <= EPart.Bass; i++) { this.dgbコンボ数[i] = new CComboStatus(); } base.On活性化(); } public override void On非活性化() { base.On非活性化(); } public override void OnManagedリソースの作成() { if (this.b活性化してない) return; // this.txCOMBOドラム = TextureFactory.tテクスチャの生成(CSkin.Path(@"Graphics\ScreenPlayDrums-combo-drums2.png")); this.tex = TextureFactory.tテクスチャの生成(CSkin.Path(@"Graphics\ScreenPlayDrums-combo-guitar2.png")); base.OnManagedリソースの作成(); } public override void OnManagedリソースの解放() { if (this.b活性化してない) return; // TextureFactory.tテクスチャの解放(ref this.txCOMBOドラム); TextureFactory.tテクスチャの解放(ref this.tex); base.OnManagedリソースの解放(); } public override int On進行描画() { if (!this.b活性化してない) { for (EPart inst = EPart.Drums; inst <= EPart.Bass; ++inst) { if (CDTXMania.Instance.ConfigIni.b楽器有効(inst) && CDTXMania.Instance.DTX.bチップがある[inst]) { EEvent e今回の状態遷移イベント; CComboStatus st = this.dgbコンボ数[inst]; // 前回と今回の COMBO 値から、e今回の状態遷移イベントを決定する。 if (st.n現在表示中のCOMBO値 == st.nCOMBO値) { e今回の状態遷移イベント = EEvent.同一数値; } else if (st.n現在表示中のCOMBO値 > st.nCOMBO値) { e今回の状態遷移イベント = EEvent.ミス通知; } else if ((st.n現在表示中のCOMBO値 < CDTXMania.Instance.ConfigIni.nMinComboDisp[inst]) && (st.nCOMBO値 < CDTXMania.Instance.ConfigIni.nMinComboDisp[inst])) { e今回の状態遷移イベント = EEvent.非表示; } else { e今回の状態遷移イベント = EEvent.数値更新; } // nジャンプインデックス値 の進行。 if (st.nジャンプインデックス値 < 360) { if ((st.n前回の時刻_ジャンプ用 == -1) || (CDTXMania.Instance.Timer.n現在時刻 < st.n前回の時刻_ジャンプ用)) { st.n前回の時刻_ジャンプ用 = CDTXMania.Instance.Timer.n現在時刻; } const long INTERVAL = 2; long diff = CDTXMania.Instance.Timer.n現在時刻 - st.n前回の時刻_ジャンプ用; st.n前回の時刻_ジャンプ用 += INTERVAL * (diff / INTERVAL); st.nジャンプインデックス値 += 3 * (int)(diff / INTERVAL); if (st.nジャンプインデックス値 >= 2000) { st.nジャンプインデックス値 -= 3 * ((st.nジャンプインデックス値 - 2000) / 3 + 1); } } Retry: // モードが変化した場合はここからリトライする。 switch (st.e現在のモード) { case EMode.非表示中: if (e今回の状態遷移イベント == EEvent.数値更新) { // モード変更 st.e現在のモード = EMode.進行表示中; st.nジャンプインデックス値 = 0; st.n前回の時刻_ジャンプ用 = CDTXMania.Instance.Timer.n現在時刻; goto Retry; } st.n現在表示中のCOMBO値 = st.nCOMBO値; break; case EMode.進行表示中: if ((e今回の状態遷移イベント == EEvent.非表示) || (e今回の状態遷移イベント == EEvent.ミス通知)) { // モード変更 st.e現在のモード = EMode.残像表示中; //st.n残像表示中のCOMBO値 = st.n現在表示中のCOMBO値; st.nコンボが切れた時刻 = CDTXMania.Instance.Timer.n現在時刻; goto Retry; } if (e今回の状態遷移イベント == EEvent.数値更新) { st.nジャンプインデックス値 = 0; st.n前回の時刻_ジャンプ用 = CDTXMania.Instance.Timer.n現在時刻; } st.n現在表示中のCOMBO値 = st.nCOMBO値; this.tコンボ表示(inst, st.nCOMBO値, st.nジャンプインデックス値); break; case EMode.残像表示中: if (e今回の状態遷移イベント == EEvent.数値更新) { // モード変更1 st.e現在のモード = EMode.進行表示中; goto Retry; } if ((CDTXMania.Instance.Timer.n現在時刻 - st.nコンボが切れた時刻) > 1000) { // モード変更2 st.e現在のモード = EMode.非表示中; goto Retry; } st.n現在表示中のCOMBO値 = st.nCOMBO値; break; } } } } return 0; } } }