▼XNA Game Studioメモ▼
ゲームパッドの利用


キー状態を見てキーイベントとして通知するライブラリ「KeyManager」を作成し、それを利用するプログラムを作成する。
Xbox 360のコントローラのボタンを押すことにより、押したボタンが画面に表示される。ボタン押した時はバイブレーションも行う。





リソースの追加
  1. はじめてのXNAアプリの作成」で作成したフォントプロセッサ「DefaultFont.spritefont」をソリューションエクスプローラのContentに追加する。
  2. グラフィックスの描画」で作成した「Graphics.cs」をプロジェクトに追加する。


KeyManagerクラスの機能
種類 メソッド 説明
初期化 KeyManager(KeyDown keyDown,KeyUp keyUp) キーイベント配信先メソッドを指定
void KeyDown(PlayerIndex index,int keyType)
void KeyUp(PlayerIndex index,int keyType)
更新 void Update() キー状態を見てキーイベントとして通知


PlayerIndex列挙型
定数 説明
One 1プレイヤー
Two 2プレイヤー
Three 3プレイヤー
Four 4プレイヤー

GamePadState構造体
変数 説明 変数 KeyManager定数 説明
GamePadButtons Buttons ボタンの状態 ButtonState A A A
ButtonState B B B
ButtonState Back BACK バック(BACK)
ButtonState LeftShoulder LEFT_SHOULDER 左ショルダー(LB)
ButtonState LeftStick LEFT_STICK 左スティック押下
ButtonState RightSoulder RIGHT_SHOULDER 右ショルダー(RB)
ButtonState RightStick RIGHT_STICK 右スティック押下
ButtonState Start START スタート(START)
ButtonState X X X
ButtonState Y Y Y
GamePadDPad DPad デジタルパッドの状態 ButtonState Left DPAD_LEFT
ButtonState Right DPAD_RIGHT
ButtonState Up DPAD_UP
ButtonState Down DPAD_DOWN
GamePadThumbSticks ThumbSticks 親指スティックの状態 Vector2 Left LPAD_LEFT
LPAD_RIGHT
LPAD_UP
LPAD_DOWN
左スティック
Vector2 Right RPAD_LEFT
RPAD_RIGHT
RPAD_UP
RPAD_DOWN
右スティック
GamePadTriggers Triggers トリガーの状態 float Left LEFT_TRIGGER 左トリガー(LT)
float Right RIGHT_TRIGGER 右トリガー(RT)
bool IsConnected 接続状態 - - -
int PacketNumber パケット番号 - - -


ソースコードの編集
GameMain.cs
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

//ゲームパッドの利用
namespace GamePadEx {
    public class GameMain : Microsoft.Xna.Framework.Game {
        private Graphics   g;   //グラフィックス
        private KeyManager km;  //キーマネージャ
        private String[]   info;//情報 

        //コンストラクタ
        public GameMain() {
            g=new Graphics(this);
            km=new KeyManager(KeyDown,KeyUp);
            info=new String[4];
            Content.RootDirectory="Content";
        }

        //初期化
        protected override void Initialize() {
            base.Initialize();
        }

        //グラフィクスコンテントの読み込み
        protected override void LoadContent() {
            g.LoadContent();
        }

        //グラフィクスコンテントの解放
        protected override void UnloadContent() {
        }

        //更新
        protected override void Update(GameTime gameTime) {
            //キーイベントの配信
            km.Update();

            //ゲームパッド状態の取得
            info[0]="Button> ";
            info[1]="DPad> ";
            info[2]="ThumbStick> ";
            info[3]="Trigger> ";
            GamePadState gp=GamePad.GetState(PlayerIndex.One);
            if (gp.IsConnected) {
                //ボタン
                if (gp.Buttons.A            ==ButtonState.Pressed) info[0]+="A ";
                if (gp.Buttons.B            ==ButtonState.Pressed) info[0]+="B ";
                if (gp.Buttons.Back         ==ButtonState.Pressed) info[0]+="BACK ";
                if (gp.Buttons.LeftShoulder ==ButtonState.Pressed) info[0]+="LEFT_SHOULDER ";
                if (gp.Buttons.LeftStick    ==ButtonState.Pressed) info[0]+="LEFT_STICK ";
                if (gp.Buttons.RightShoulder==ButtonState.Pressed) info[0]+="RIGHT_SHOULDER ";
                if (gp.Buttons.RightStick   ==ButtonState.Pressed) info[0]+="RIGHT_STICK ";
                if (gp.Buttons.Start        ==ButtonState.Pressed) info[0]+="START ";
                if (gp.Buttons.X            ==ButtonState.Pressed) info[0]+="X ";
                if (gp.Buttons.Y            ==ButtonState.Pressed) info[0]+="Y ";

                //デジタルパッド
                if (gp.DPad.Left ==ButtonState.Pressed) info[1]+="LEFT ";
                if (gp.DPad.Right==ButtonState.Pressed) info[1]+="RIGHT ";
                if (gp.DPad.Up   ==ButtonState.Pressed) info[1]+="UP ";
                if (gp.DPad.Down ==ButtonState.Pressed) info[1]+="DOWN ";

                //親指スティック
                info[2]+="LEFT("+gp.ThumbSticks.Left.X+","+gp.ThumbSticks.Left.Y+") ";
                info[2]+="RIGHT("+gp.ThumbSticks.Right.X+","+gp.ThumbSticks.Right.Y+") ";

                //トリガー
                info[3]+="LEFT("+gp.Triggers.Left+") ";
                info[3]+="RIGHT("+gp.Triggers.Right+") ";
            }
            
            //ベースの更新
            base.Update(gameTime);
        }
       
        //キーダウン
        private void KeyDown(PlayerIndex index,int keyType) {
            if (index==PlayerIndex.One) {
                //バイブレーションON
                GamePad.SetVibration(PlayerIndex.One,1.0f,1.0f);

                //終了
                if (keyType==KeyManager.BACK) Exit();
            }
        }

        //キーアップ
        private void KeyUp(PlayerIndex index,int keyType) {
            if (index==PlayerIndex.One) {
                //バイブレーションOFF
                GamePad.SetVibration(PlayerIndex.One,0.0f,0.0f);
            }
        }

        //描画
        protected override void Draw(GameTime gameTime) {
            //背景の描画
            g.SetColor(255,255,255);
            g.Clear();

            //文字列の描画
            g.SetColor(0,0,0);
            for (int i=0;i<4;i++) {
                g.DrawString(info[i],50,50+50*i);
            }

            //ベースの描画
            base.Draw(gameTime);
        }   
    }
}


KeyManager.cs
using System;
using System.IO;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;

//キーマネージャ
public class KeyManager {
    //キー定数
    public const int 
        A             =0,
        B             =1,
        BACK          =2,
        LEFT_SHOULDER =3,
        LEFT_STICK    =4,
        RIGHT_SHOULDER=5,
        RIGHT_STICK   =6,
        START         =7,
        X             =8,
        Y             =9,
        DPAD_LEFT     =10,
        DPAD_RIGHT    =11,
        DPAD_UP       =12,
        DPAD_DOWN     =13,
        LPAD_LEFT     =14,
        LPAD_RIGHT    =15,
        LPAD_UP       =16,
        LPAD_DOWN     =17,
        RPAD_LEFT     =18,
        RPAD_RIGHT    =19,
        RPAD_UP       =20,
        RPAD_DOWN     =21,
        LEFT_TRIGGER  =22,
        RIGHT_TRIGGER =23;

    //デリゲート
    public delegate void KeyDown(PlayerIndex index,int keyType);
    public delegate void KeyUp(PlayerIndex index,int keyType);
    private KeyDown keyDown;
    private KeyUp   keyUp;

    //前キー状態
    private GamePadState[] keyStateP=new GamePadState[4];


//====================
//初期化
//====================
    //初期化
    public KeyManager(KeyDown keyDown,KeyUp keyUp) {
        this.keyDown=keyDown;
        this.keyUp=keyUp;
    }


//====================
//キーイベント
//====================
    //キーイベントの更新
    public void Update() {
        PlayerIndex[] index={
            PlayerIndex.One,
            PlayerIndex.Two,
            PlayerIndex.Three,
            PlayerIndex.Four};

        for (int i=0;i<4;i++) {
            //キー状態の取得
            GamePadState keyState=GamePad.GetState(index[i]);
            if (!keyState.IsConnected) return;            

            //ボタンイベントの配信
            ButtonState[] ks={
                keyState.Buttons.A,
                keyState.Buttons.B,
                keyState.Buttons.Back,
                keyState.Buttons.LeftShoulder,
                keyState.Buttons.LeftStick,
                keyState.Buttons.RightShoulder,
                keyState.Buttons.RightStick,
                keyState.Buttons.Start,
                keyState.Buttons.X,
                keyState.Buttons.Y,
                keyState.DPad.Left,
                keyState.DPad.Right,
                keyState.DPad.Up,
                keyState.DPad.Down};
            ButtonState[] ksp={
                keyStateP[i].Buttons.A,
                keyStateP[i].Buttons.B,
                keyStateP[i].Buttons.Back,
                keyStateP[i].Buttons.LeftShoulder,
                keyStateP[i].Buttons.LeftStick,
                keyStateP[i].Buttons.RightShoulder,
                keyStateP[i].Buttons.RightStick,
                keyStateP[i].Buttons.Start,
                keyStateP[i].Buttons.X,
                keyStateP[i].Buttons.Y,
                keyStateP[i].DPad.Left,
                keyStateP[i].DPad.Right,
                keyStateP[i].DPad.Up,
                keyStateP[i].DPad.Down};
            for (int j=0;j<14;j++) {
                if (ks[j]!=ksp[j]) {
                    if (ks[j]==ButtonState.Pressed) {
                        if (keyDown!=null) keyDown(index[i],j);
                    } else {
                        if (keyUp!=null) keyUp(index[i],j);
                    }
                }
            }

            //親指パッドの配信
            float[] tp={
                -keyState.ThumbSticks.Left.X,
                keyState.ThumbSticks.Left.X,
                keyState.ThumbSticks.Left.Y,
                -keyState.ThumbSticks.Left.Y,
                -keyState.ThumbSticks.Right.X,
                keyState.ThumbSticks.Right.X,
                keyState.ThumbSticks.Right.Y,
                -keyState.ThumbSticks.Right.Y};
            float[] tpp={
                -keyStateP[i].ThumbSticks.Left.X,
                keyStateP[i].ThumbSticks.Left.X,
                keyStateP[i].ThumbSticks.Left.Y,
                -keyStateP[i].ThumbSticks.Left.Y,
                -keyStateP[i].ThumbSticks.Right.X,
                keyStateP[i].ThumbSticks.Right.X,
                keyStateP[i].ThumbSticks.Right.Y,
                -keyStateP[i].ThumbSticks.Right.Y};
            for (int j=0;j<8;j++) {
                if (tp[j]>0 && tpp[j]==0) {
                    if (keyDown!=null) keyDown(index[i],j+14);
                } else if (tp[j]==0 && tpp[j]>0) {
                    if (keyUp!=null) keyUp(index[i],j+14);
                }
            }

            //トリガーイベントの配信
            float[] tg={
                keyState.Triggers.Left,
                keyState.Triggers.Right};
            float[] tgp={
                keyStateP[i].Triggers.Left,
                keyStateP[i].Triggers.Right};
            for (int j=0;j<2;j++) {
                if (tg[j]!=0 && tgp[j]==0) {
                    if (keyDown!=null) keyDown(index[i],j+22);
                } else if (tg[j]==0 && tgp[j]!=0) {
                    if (keyUp!=null) keyUp(index[i],j+22);
                }
            }

            //前キー状態
            keyStateP[i]=keyState;
        }
    }
}



−戻る−