//* ────────────-_______________________* //* constructor & destructor ───────────────────────* //* -----------------------------------------------------------------------* /// <summary>静的なコンストラクタ。</summary> /// <remarks>ここで加速度グラフ情報を作成します。</remarks> static CBall() { List <float> graph = new List <float>(); float fPrevSpeed = 0f; for (SPhase phase = SPhase.initialized; phase < 3; phase.count++) { int nPCount = phase.countPhase; int nPLimit = accelerateTime[phase]; float fSpeed = MAX_SPEED; switch (phase) { case 0: fSpeed = CInterpolate.lerpClampInOutQuad(0, MAX_SPEED, nPCount, nPLimit); break; case 2: fSpeed = CInterpolate.lerpClampInQuad(MAX_SPEED, 0, nPCount, nPLimit); break; } graph.Add(fSpeed); fPrevSpeed = fSpeed; phase.reserveNextPhase = nPCount >= nPLimit; } speedGraph = graph.AsReadOnly(); enemy = new CBall(); player = new CBall(); }
//* ────────────-_______________________* //* constructor & destructor ───────────────────────* //* -----------------------------------------------------------------------* /// <summary>静的なコンストラクタ。</summary> /// <remarks>ここで加速度グラフ情報を作成します。</remarks> static CBall() { List <float> graph = new List <float>(); float fPrevSpeed = 0f; for (SPhase phase = SPhase.initialized; phase < 3; phase.count++) { int nPCount = phase.countPhase; int nPLimit = accelerateTime[phase]; float fSpeed = MAX_SPEED; switch (phase) { case 0: fSpeed = CInterpolate._clampSlowFastSlow(0, MAX_SPEED, nPCount, nPLimit); break; case 2: fSpeed = CInterpolate._clampAccelerate(MAX_SPEED, 0, nPCount, nPLimit); break; } graph.Add(fSpeed - fPrevSpeed); fPrevSpeed = fSpeed; phase.reserveNextPhase = nPCount >= nPLimit; } accelerateGraph = graph.AsReadOnly(); }
//* -----------------------------------------------------------------------* /// <summary>グラデーション計算をします。</summary> /// /// <param name="nNow">現在値</param> /// <param name="nSize">分割数</param> /// <returns>補完値</returns> public float smooth(int nNow, int nSize) { if (limit1 == limit2) { return(limit1); } return(MathHelper.Clamp(CInterpolate._clampSmooth(start, end, nNow, nSize), MathHelper.Min(limit1, limit2), MathHelper.Max(limit1, limit2))); }
//* ────________________________________* //* methods ───────────────────────────────-* //* -----------------------------------------------------------------------* /// <summary>現在のカメラ情報を取得します。</summary> /// /// <param name="now">現在の時間。</param> /// <returns>現在のカメラ情報。</returns> public SData getNow(int now) { SData data = new SData(); float amount = 0.5f * (interpolate.interpolate(0, 1, now, interval) + CInterpolate.amountLinear(now, interval)); data.up = Vector3.Lerp(start.up, end.up, amount); data.from = Vector3.Lerp(start.from, end.from, amount); data.to = Vector3.Lerp(start.to, end.to, amount); data.fov = MathHelper.Lerp(start.fov, end.fov, amount); return(data); }
//* -----------------------------------------------------------------------* /// <summary>音量値を文字列化します。</summary> /// /// <param name="bSlider">スライダーを挿入するかどうか</param> /// <returns>文字列化した音量値</returns> public string ToString(bool bSlider) { string strResult = ""; string strDB = String.Format("{0:+0.0;-0.0;0}dB", dB); if (bSlider) { char[] szVolume = new string( '・', 10 ).ToCharArray(); szVolume[( int )MathHelper.Min(CInterpolate.smooth(0, 10, volume, 2), 9)] = '◆'; strResult += new string( szVolume ) + Environment.NewLine; strDB = string.Format("({0})", strDB); } return(strResult + strDB); }
//* -----------------------------------------------------------------------* /// <summary>音量値を文字列化します。</summary> /// /// <param name="bSlider">スライダーを挿入するかどうか</param> /// <returns>文字列化した音量値</returns> public string ToString(bool bSlider) { string strResult = string.Empty; string strDB = String.Format("{0:+00.0;-00.0;+00.0}dB", dB); if (bSlider) { char[] szVolume = new string('.', 10).ToCharArray(); int cursor = (int)MathHelper.Min( CInterpolate.lerpClampLinear(0, 10, volume, MAX_VOLUME), 9); szVolume[cursor] = 'V'; strResult += new string(szVolume) + Environment.NewLine; strDB = string.Format("({0})", strDB); } return(strResult + strDB); }
//* -----------------------------------------------------------------------* /// <summary>1フレーム分の更新処理を実行します。</summary> /// /// <param name="entity">この状態を適用されているオブジェクト。</param> /// <param name="privateMembers"> /// オブジェクトと状態クラスのみがアクセス可能なフィールド。 /// </param> /// <param name="gameTime">前フレームが開始してからの経過時間。</param> public override void update(CFont entity, object privateMembers, GameTime gameTime) { if (entity.counter % 60 == 0) { int fpsUpdate = calcurator.fpsUpdate; int fpsDraw = calcurator.fpsDraw; if (prevFPSUpdate != fpsUpdate || prevFPSDraw != fpsDraw) { prevFPSUpdate = fpsUpdate; prevFPSDraw = fpsDraw; entity.color = Color.Lerp(Color.White, Color.Red, CInterpolate._amountLoopSlowdown( Math.Min(Math.Abs(60 - fpsUpdate), redzone), redzone)); entity.text = string.Format(text, fpsUpdate.ToString(), fpsDraw.ToString()); } } adaptee.update(entity, privateMembers, gameTime); }
//* ────________________________________* //* methods ───────────────────────────────-* //* -----------------------------------------------------------------------* /// <summary>ボタン入力を検出します。</summary> /// <remarks> /// 注意: このメソッドを呼び出すと、自動的に登録されているクラスに対して /// <c>update()</c>が実行されます。レガシ ゲームパッドが高位入力管理クラスにて /// アクティブの状態でこのメソッドを呼び出すと、高位入力側の判定が /// 1フレーム分欠落します。 /// </remarks> /// /// <param name="gameTime">前フレームが開始してからの経過時間。</param> /// <returns> /// ボタン入力が検出されたデバイスの管理クラス。検出しなかった場合、<c>null</c>。 /// </returns> public CLegacyInput detectInput(GameTime gameTime) { CLegacyInput result = null; int threshold = (int)CInterpolate.lerpClampLinear(0, CLegacyInput.RANGE, this.threshold, 1); for (int i = inputList.Count; --i >= 0 && result == null;) { CLegacyInput input = inputList[i]; input.update(gameTime); JoystickState state = input.nowInputState; if (state.Equals(input.prevInputState) && ( Array.Exists <byte>(state.GetButtons(), b => b != 0) || Math.Abs(state.X) >= threshold || Math.Abs(state.Y) >= threshold || Math.Abs(state.Z) >= threshold)) { result = input; } } return(result); }
//* -----------------------------------------------------------------------* /// <summary>1フレーム分の描画処理を実行します。</summary> private IEnumerator coAlpha() { const int FADETIME = 60; for ( int i = 0; i < FADETIME; m_fAlpha = CInterpolate._clampAccelerate(0, 1, ++i, FADETIME) ) { yield return(null); } for (int i = 0; i < 120; i++) { yield return(null); } for ( int i = 0; i < FADETIME; m_fAlpha = CInterpolate._clampAccelerate(1, 0, ++i, FADETIME) ) { yield return(null); } phaseManager.reserveNextPhase = true; }
//* -----------------------------------------------------------------------* /// <summary>1フレーム分の更新処理を実行します。</summary> /// /// <param name="entity">この状態を適用されているオブジェクト。</param> /// <param name="privateMembers"> /// オブジェクトと状態クラスのみがアクセス可能なフィールド。 /// </param> /// <param name="gameTime">前フレームが開始してからの経過時間。</param> public override void update( CAdapter entity, CAdapter.CPrivateMembers privateMembers, GameTime gameTime) { entity.lowerInput.update(gameTime); IList <int> assign = entity.assignList; List <SInputInfo> buttons = privateMembers.buttonList; JoystickState nowState = entity.lowerInput.nowInputState; float threshold = entity.threshold; byte[] buffer = nowState.GetButtons(); for (int i = assign.Count; --i >= 0;) { int id = assign[i]; if (id >= 0) { buttons[i] = buttons[i].updateVelocity(Vector3.UnitZ * CInterpolate._amountSmooth(buffer[id], byte.MaxValue)); } else { buttons[i] = processorList[-id](buttons[i], nowState, entity); } } }
//* -----------------------------------------------------------------------* /// <summary>低~中難易度状態の移動判定を実行します。</summary> /// /// <param name="entity">この状態を適用されているオブジェクト。</param> /// <returns>移動と判断した場合、<c>true</c>。</returns> private bool movePatternLowLevel(CBall entity) { return(entity.counter % MathHelper.Lerp(40, 6, CInterpolate._amountSlowdown(m_wLevel, 5)) == 0); }
//* -----------------------------------------------------------------------* /// <summary>音量を指定したピーク値でノーマライズします。</summary> /// /// <param name="expr">ノーマライズ対象の値。</param> /// <param name="peak">ピーク値。</param> /// <returns>ノーマライズされた値。</returns> public static SVolume normalize(SVolume expr, SVolume peak) { return(CInterpolate.lerpClamp(0, peak.volume, expr / MAX_VOLUME)); }
//* -----------------------------------------------------------------------* /// <summary>加速変化する内分カウンタです。</summary> /// /// <param name="start"><paramref name="now"/>が0と等しい場合の値</param> /// <param name="end"> /// <paramref name="now"/>が<paramref name="limit"/>と等しい場合の値 /// </param> /// <param name="now">現在時間</param> /// <param name="limit"><paramref name="end"/>に到達する時間</param> /// <returns> /// 0から<paramref name="limit"/>までの<paramref name="now"/>に相当する /// <paramref name="start"/>から<paramref name="end"/>までの値 /// </returns> private byte interpolate(float start, float end, float now, float limit) { float result = CInterpolate.lerpClampInQuad(start, end, now, limit); return((byte)((int)(result / 16) * 16)); }
//* -----------------------------------------------------------------------* /// <summary>低~中難易度状態の移動判定を実行します。</summary> /// /// <param name="entity">この状態を適用されているオブジェクト。</param> /// <returns>移動と判断した場合、<c>true</c>。</returns> private bool movePatternLowLevel(CBall entity) { return(entity.counter % (int)MathHelper.Lerp( 40, 6, CInterpolate.amountOutQuadClamp(CCursor.instance.level, 5)) == 0); }
//* -----------------------------------------------------------------------* /// <summary>加速変化する内分カウンタです。</summary> /// /// <param name="start"><paramref name="now"/>が0と等しい場合の値</param> /// <param name="end"> /// <paramref name="now"/>が<paramref name="limit"/>と等しい場合の値 /// </param> /// <param name="now">現在時間</param> /// <param name="limit"><paramref name="end"/>に到達する時間</param> /// <returns> /// 0から<paramref name="limit"/>までの<paramref name="now"/>に相当する /// <paramref name="start"/>から<paramref name="end"/>までの値 /// </returns> private byte interpolate(float start, float end, float now, float limit) { float result = CInterpolate._clampAccelerate(start, end, now, limit); return((byte)((int)(result / 16) * 16)); }