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();
}
}