ジョイスティック(ゲームパッド)の使い方

PTBでは簡単にジョイスティック(ゲームパッド)を利用することができます。Windowsにしか対応していないジョイスティックであっても、MacのPTBで利用することが可能なようです。PTBのジョイスティック関数は、Macのほうが充実しています。

・・・といっても、Macでジョイスティックを利用できるようになるまでに結構苦労をしまして。。。参考までに記載しておきます。
私の環境では、Mac ProでUSB接続のApple純正キーボードを利用しており、さらにそのキーボードにApple純正のUSBマウスをつないでいたら、ジョイスティックが正しく動作しませんでした。
原因がよく分からないのですが、Apple純正のUSBマウスをキーボードからはずして、Mac Pro本体に一般的な(Apple純正ではない)USBマウスを接続させたところ、不具合が解消されました。(キーボードは変更していません)

ジョイスティックをパソコンに接続した状態で

PsychHIDTest

を実行してください。

次のような結果が出力されるはずです。

TestPsychHID
Making a list of all your HID-compliant devices. ...
You have 5 HID-compliant devices:
device 1: Consumer Usage 0x1, , Apple Mikey HID Driver, 8 inputs, 0 outputs
device 2: Joystick, Madcatz, Mad Catz V.1 Stick, 12 inputs, 0 outputs
device 3: Mouse, Logitech, USB Optical Mouse, 6 inputs, 0 outputs
device 4: Consumer Usage 0x1, Apple Inc., Apple Keyboard, 7 inputs, 0 outputs
device 5: Keyboard, Apple Inc., Apple Keyboard, 271 inputs, 5 outputs
Test keyboard.
device 5: Apple Inc., Apple Keyboard
Now flickering the LEDs on your keyboard. ... Success!!
Now reading your keyboard. Press any key to continue. ... Thanks.
Test mouse.
device 3: Logitech, USB Optical Mouse
Now reading your mouse. Move the mouse to continue. ... Thanks.

上記の例では、device 2としてジョイスティックが認識されていることが分かります。

MacではGamepadと呼ばれる関数を利用することができます。

WindowsではGamepad関数が非対応(2013年9月時点)なので、PsychHID関数を利用します。

GamepadおよびPsychHID関数の利用方法は、コマンドウィンドウに関数名を入力してエンターキーを押すと確認できます。

そのほかの便利な関数として次のようなものもあります。

  • AxisCenter
  • AxisMax
  • AxisMin
  • AxisLeft
  • AxisRight
  • AxisUp
  • AxisDown

以下が、ジョイスティックを利用するサンプルプログラムです。

function gamepadtest
% 起動後、いずれかのキーを押してください。指定した時間のあいだ、ジョイスティックの状態を確認することができます。
% 呼び出しておいたほうがよい関数たち。
AssertOpenGL; 
KbName('UnifyKeyNames');
ListenChar(2); % Matlabに対するキー入力を無効
%myKeyCheck; % 外部ファイル
GetSecs;
WaitSecs(0.1);
rand('state', sum(100*clock));
%HideCursor;
%----------------------
% 背景色 
bgColor = [128 128 128]; %RGBの値
%-------------------------
try
  
    % 刺激を呈示するディスプレイ(ウィンドウ)の設定
    screenNumber = max(Screen('Screens'));
    
    % デバッグ用。ウィンドウでの呈示
    %[windowPtr, windowRect] = Screen('OpenWindow', screenNumber, bgColor, [10 50 750 550]);
    % 実験用。フルスクリーン
    [windowPtr, windowRect] = Screen('OpenWindow', screenNumber, bgColor);
            
    gamepadIndex = 1; % たぶん大部分の環境では1だと思います。うまくいかないときは適当に変更してみてください。
    
    % Gamepad関数に対応しているのはMacだけです。Windowsではコメントアウトしてください。
    gamepadName = Gamepad('GetGamepadNamesFromIndices', gamepadIndex)
    numButtons = Gamepad('GetNumButtons', gamepadIndex)
    numAxes = Gamepad('GetNumAxes', gamepadIndex)
    numBalls = Gamepad('GetNumBalls', gamepadIndex)
    numHats = Gamepad('GetNumHats', gamepadIndex)    
    
    KbWait([], 3); % いずれかのキーを押すとジョイスティックの状態を確認できます。
    
    startTime = GetSecs;
    
    while (GetSecs - startTime) < 10 % ここで指定した時間のあいだ、ジョイスティックの状態をリアルタイムで確認できます。
        DrawFormattedText(windowPtr, num2str(GetSecs - startTime), 10, 10);
        
        % numAxesの数だけ記述してください。
        axisState1 = Gamepad('GetAxis', gamepadIndex, 1);
        DrawFormattedText(windowPtr, num2str(axisState1), 100, 100);
        
        axisState2 = Gamepad('GetAxis', gamepadIndex, 2);
        DrawFormattedText(windowPtr, num2str(axisState2), 100, 150);
        
        axisState3 = Gamepad('GetAxis', gamepadIndex, 3);
        DrawFormattedText(windowPtr, num2str(axisState3), 100, 200);
        
        
        % numButtonsの数だけ記述してください。
        buttonState1 = Gamepad('GetButton', gamepadIndex, 1);
        DrawFormattedText(windowPtr, num2str(buttonState1), 200, 100);
        
        buttonState2 = Gamepad('GetButton', gamepadIndex, 2);
        DrawFormattedText(windowPtr, num2str(buttonState2), 200, 150);
        
        buttonState3 = Gamepad('GetButton', gamepadIndex, 3);
        DrawFormattedText(windowPtr, num2str(buttonState3), 200, 200);
        
        
        % WindowsではPsychHID関数を使います。
        deviceNumber = 2; % PsychHIDTestで確認したデバイス番号を指定します。
        rawState = PsychHID('RawState', deviceNumber, 1);
        DrawFormattedText(windowPtr, num2str(rawState), 500, 100);
        rawState = PsychHID('RawState', deviceNumber, 2);
        DrawFormattedText(windowPtr, num2str(rawState), 500, 130);
        rawState = PsychHID('RawState', deviceNumber, 3);
        DrawFormattedText(windowPtr, num2str(rawState), 500, 160);
        rawState = PsychHID('RawState', deviceNumber, 4);
        DrawFormattedText(windowPtr, num2str(rawState), 500, 190);
        rawState = PsychHID('RawState', deviceNumber, 5);
        DrawFormattedText(windowPtr, num2str(rawState), 500, 220);
        
        Screen('Flip', windowPtr); 
        WaitSecs(0.1); % サンプリング間隔
    end;
    
    vbl1 = Screen('Flip', windowPtr); 
    KbWait([], 3);
 
    %終了処理
    
    Screen('CloseAll');
    ShowCursor;
    ListenChar(0);
 
    
    
catch % 以下はプログラムを中断したときのみ実行される。
    
    
    Screen('CloseAll');
    ShowCursor;
    ListenChar(0);
    psychrethrow(psychlasterror);
end