using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; /// /// ボタン状態インターフェイス /// public interface I_KeyboardButtonState { uint RepeatIntervalCnt { get; } bool Repeated { get; } bool Pressed { get; } bool JustPressed { get; } uint PressedCnt { get; } } public interface I_KeyboardState { KeyboardState Previous { get; } KeyboardState Current { get; } I_KeyboardButtonState ARROW_UP {get;} I_KeyboardButtonState ARROW_DOWN { get; } I_KeyboardButtonState ARROW_LEFT { get; } I_KeyboardButtonState ARROW_RIGHT { get; } I_KeyboardButtonState ENTER { get; } I_KeyboardButtonState SPACE { get; } } /// /// ボタン押下繰り返しクラス /// public class Repeat { private uint m_iFirstIntervalCnt; private uint m_iRepeatIntervalCnt; private uint m_iCount; private uint m_iFirstInterval; private uint m_iRepeatInterval; // リピート状態列挙体 public enum RepeatState : byte { Released = 0, // 開放 FirstPress, // 最初に押下した状態 FirstInterval, // 最初に押下したインターバル状態 RepeatPress, // 繰り返し押下した状態 RepeatInterval // 繰り返し押下したインターバル状態 } private RepeatState m_rsState; // プロパティ public uint RepeatIntervalCnt { get { return this.m_iCount; } } // 規定リピートインターバルを繰り返した回数 public uint FirstInterVal { set { this.m_iFirstInterval = value; } // 初回インターバル規定値 get { return this.m_iFirstInterval; } } public uint RepeatInterval { set { this.m_iRepeatInterval = value; } // 2回目以降インターバル規定値 get { return this.m_iRepeatInterval; } } public bool Repeated { get { return (m_rsState == RepeatState.FirstPress || // インターバルを終え、再度押下状態となったか m_rsState == RepeatState.RepeatPress); } } public RepeatState State { get { return this.m_rsState; } } // 現在のリピード状態 //**************************// // コンストラクタ // //**************************// public Repeat(uint iFirstInterval, uint iRepeatInterval) { this.m_iFirstInterval = iFirstInterval; this.m_iFirstIntervalCnt = 0; this.m_iRepeatInterval = iRepeatInterval; this.m_iRepeatIntervalCnt = 0; this.m_iCount = 0; this.m_rsState = RepeatState.Released; } //**************************// // 各入力更新処理関数 // //**************************// public void Update(bool bsState) { // 現在押下状態ではない if (!bsState) { m_iFirstIntervalCnt = 0; m_iRepeatIntervalCnt = 0; m_rsState = RepeatState.Released; m_iCount = 0; } // 押下状態にある else { switch (m_rsState) { case RepeatState.Released: m_rsState = RepeatState.FirstPress; // 初期押下状態に変更 m_iFirstIntervalCnt = 0; m_iRepeatIntervalCnt = 0; m_iCount++; break; case RepeatState.FirstPress: m_rsState = RepeatState.FirstInterval; // 初期押下インターバル状態に変更 break; case RepeatState.FirstInterval: m_iFirstIntervalCnt++; if (m_iFirstIntervalCnt >= m_iFirstInterval) { // インターバルカウントが規定カウントを超えた場合 m_rsState = RepeatState.RepeatPress; // 繰り返し押下状態に変更 m_iFirstIntervalCnt = 0; m_iCount++; } break; case RepeatState.RepeatPress: m_rsState = RepeatState.RepeatInterval; // 繰り返しインターバル状態に変更 break; case RepeatState.RepeatInterval: m_iRepeatIntervalCnt++; if (m_iRepeatIntervalCnt >= m_iRepeatInterval) { // インターバルカウントが規定カウントを超えた場合 m_rsState = RepeatState.RepeatPress; // 繰り返し押下状態に変更 m_iRepeatIntervalCnt = 0; m_iCount++; } break; } } } //**************************// // 各入力更新処理関数 // //**************************// public void UpdateStick(float fValue) { // 現在押下状態ではない if (fValue == 0.0f) { m_iFirstIntervalCnt = 0; m_iRepeatIntervalCnt = 0; m_rsState = RepeatState.Released; m_iCount = 0; } // 押下状態にある else { switch (m_rsState) { case RepeatState.Released: m_rsState = RepeatState.FirstPress; // 初期押下状態に変更 m_iFirstIntervalCnt = 0; m_iRepeatIntervalCnt = 0; m_iCount++; break; case RepeatState.FirstPress: m_rsState = RepeatState.FirstInterval; // 初期押下インターバル状態に変更 break; case RepeatState.FirstInterval: m_iFirstIntervalCnt++; if (m_iFirstIntervalCnt >= m_iFirstInterval) { // インターバルカウントが規定カウントを超えた場合 m_rsState = RepeatState.RepeatPress; // 繰り返し押下状態に変更 m_iFirstIntervalCnt = 0; m_iCount++; } break; case RepeatState.RepeatPress: m_rsState = RepeatState.RepeatInterval; // 繰り返しインターバル状態に変更 break; case RepeatState.RepeatInterval: m_iRepeatIntervalCnt++; if (m_iRepeatIntervalCnt >= m_iRepeatInterval) { // インターバルカウントが規定カウントを超えた場合 m_rsState = RepeatState.RepeatPress; // 繰り返し押下状態に変更 m_iRepeatIntervalCnt = 0; m_iCount++; } break; } } } } /// /// ボタン押下情報 /// public class KeyboardInputState : Repeat, I_KeyboardButtonState { private bool m_bPressed; private bool m_bJustPressed; private uint m_iPressedCnt; public bool Pressed { get { return this.m_bPressed; } } // 押下状態であるか public bool JustPressed { get { return this.m_bJustPressed; } } // 現フレームで押下状態になっているか public uint PressedCnt { get { return this.m_iPressedCnt; } } // 連続押下フレーム数 /// /// コンストラクタ /// /// /// public KeyboardInputState(uint iFirstInterval, uint iRepeatInterval) : base(iFirstInterval, iRepeatInterval) { // ボタン押下していない状態で情報を初期化する this.Update(false); } /// /// 更新 /// /// public new void Update(bool bsCurrent) /* new の理由→RepeatクラスにもUpdate関数が存在し、このUpdateはオーバーライドしないという明示的なもの */ { bool bsPrevious; // 現フレームボタン押下情報を直前フレームボタン押下情報へコピー bsPrevious = m_bPressed; // ボタンが押下状態の場合、現フレームボタン押下情報を押下状態にする if (bsCurrent) { m_bPressed = true; } else { m_bPressed = false; } // 今回のフレームで初めて押下されたのかチェック if ((!bsPrevious) && (bsCurrent)) { m_bJustPressed = true; } else { m_bJustPressed = false; } // 押下状態の場合、連続押下時間をカウントアップ if (bsCurrent) { m_iPressedCnt++; } else { m_iPressedCnt = 0; } // 今回のフレームが押下状態ではない場合、カウントを0にクリアする // 親クラス(Repeat)のUpdateを実行する base.Update(bsCurrent); } } public sealed class KeyboardPropaerty { public class KeyboardInput : I_KeyboardState { private enum KeyboardKeyIndex: byte { ARROW_UP = 0, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ENTER, SPACE, KEYBOARD_KEY_MAX } private KeyboardState m_kbPrev, m_kbCurr; private KeyboardInputState[] m_kbButtons; public KeyboardState Previous { get { return this.m_kbPrev; } } public KeyboardState Current { get { return this.m_kbCurr; } } public I_KeyboardButtonState ARROW_UP {get{return(m_kbButtons[(int)KeyboardKeyIndex.ARROW_UP]);}} public I_KeyboardButtonState ARROW_DOWN { get { return (m_kbButtons[(int)KeyboardKeyIndex.ARROW_DOWN]); } } public I_KeyboardButtonState ARROW_LEFT { get { return (m_kbButtons[(int)KeyboardKeyIndex.ARROW_LEFT]); } } public I_KeyboardButtonState ARROW_RIGHT { get { return (m_kbButtons[(int)KeyboardKeyIndex.ARROW_RIGHT]); } } public I_KeyboardButtonState ENTER{ get { return (m_kbButtons[(int)KeyboardKeyIndex.ENTER]); } } public I_KeyboardButtonState SPACE { get { return (m_kbButtons[(int)KeyboardKeyIndex.SPACE]); } } /// /// コンストラクタ /// /// public KeyboardInput() { m_kbButtons = new KeyboardInputState[(int)KeyboardKeyIndex.KEYBOARD_KEY_MAX]; for (byte i = 0; i < m_kbButtons.Length; i++) { m_kbButtons[i] = new KeyboardInputState(30, 10); } this.Update(); } /// /// 更新 /// public void Update() { // 直前フレームのコントローラ情報を格納 m_kbPrev = m_kbCurr; // 現フレームのコントローラ情報を取得 m_kbCurr = Keyboard.GetState(); // 各ボタン押下状態 m_kbButtons[(int)KeyboardKeyIndex.ARROW_UP].Update(m_kbCurr.IsKeyDown(Keys.Up)); m_kbButtons[(int)KeyboardKeyIndex.ARROW_DOWN].Update(m_kbCurr.IsKeyDown(Keys.Down)); m_kbButtons[(int)KeyboardKeyIndex.ARROW_LEFT].Update(m_kbCurr.IsKeyDown(Keys.Left)); m_kbButtons[(int)KeyboardKeyIndex.ARROW_RIGHT].Update(m_kbCurr.IsKeyDown(Keys.Right)); m_kbButtons[(int)KeyboardKeyIndex.ENTER].Update(m_kbCurr.IsKeyDown(Keys.Enter)); m_kbButtons[(int)KeyboardKeyIndex.SPACE].Update(m_kbCurr.IsKeyDown(Keys.Space)); } } private KeyboardInput m_KeyboardInput; public KeyboardInput GetKeyboardInput{get{return this.m_KeyboardInput;}} /// /// コンストラクタ /// public KeyboardPropaerty() { m_KeyboardInput = new KeyboardInput(); } /// /// キー入力更新 /// public void Update() { m_KeyboardInput.Update(); } }