雑念日記

主に技術的なことをつらとらと(書ければいいな)。

Processingでゲームパッドを使おう (その2)

関連記事。


前回(Processingでゲームパッドを使おう (その1) - 雑念日記)の続き。
前回同様、GameControlPlusというライブラリを使います。

今回は以下のように設定ファイルによってゲームパッドを使う方法についての詳細。

ControlIO control = ControlIO.getInstance(this);
ControlDevice device = control.getMatchedDevice("gamepad_config");

上の例だと、対象のスケッチのdataディレクトリにある「gamepad_config」という名前のファイルを読み込みます。名前は自由に変更できます。

フォーマットについて

フォーマットは次のようなもの。

My GamePad Configuration
X_POS   X position   3  SLIDER  x        0  1.0  0.15
Y_POS   Y Position   3  SLIDER  y        0  1.0  0.15
B_0     Button 0     1  BUTTON  Trigger  0  0.0  0.0
B_1     BUtton 1     1  BUTTON  Thumb    0  0.0  0.0

1行目(My GamePad Configuration)はこの設定ファイルの概要や説明などを記述します。特にフォーマットは決まっていないので、開発者が好きに記述することが出来ます。
2行目以降は入力項目についての設定を記述します。TAB区切りで8個のカラムからなっており、何行でも記述可能です。

8個のカラムについては以下に概要をまとめます。

番号 説明
1番目 入力項目の名前、自由に名付けることが可能
2番目 入力項目の概要、自由に記述することが可能
3番目 入力項目の種別 (1: ボタン、2: ハット、3: スライダー のいずれか)
4番目 入力項目の種別、3番目と対応 (BUTTON, HAT, SLIDER のいずれか)
5番目 入力項目の実際の名前
6番目 接続番号、将来的に複数接続が可能になる?基本0でOK
7番目 乗数
8番目 トレランス(許容値)、0から1の間で設定

ボタンは通常のボタン、スライダーは十字キーやスティックのような縦横の操作が可能なもの、ハットはジョイスティックの先端に付いているボタンのことらしいです。

各項目の詳細

1番目: 入力項目の名前

デバイスを取得後、デバイスからここで定めた名前を使ってボタンやスライダーなどを取得することが出来ます。

ControlDevice device = control.getMatchedDevice("gamepad_config");
ControlSlider slider = device.getSlider("X_POS");
ControlButton button = device.getButton("B_0");
5番目: 入力項目の実際の名前

設定を割り当てるボタンを特定するために、そのデバイス(ゲームパッド)によって決められているアクセス可能な名称を指定します。
と言われても、そんな名前わかるかいっちゅう話です。

そのあたりはちゃんとケアされていて、例えばProcessingのエディタから辿れるGameControlPlusのExampleのひとつ、「Gcp_ShowDevices」をゲームパッドを接続した状態で実行すると、以下のようなウィンドウが表示されます。(「Gcp_ShowDevices」の実行には別途G4Pというライブラリが必要なのでインストールしましょう。)

f:id:hoshi_sano:20140612024327j:plain

現在利用可能なデバイスの詳細を表示してくれます。僕の購入したゲームパッドでは次のような表示になりましたが、この中の「Name」の部分を参照すれば5番目のカラムに記述すべき名前がわかります。

  ========================================================================
  NAME :     USB,2-axis 8-button gamepad  
  Type :     Stick
  Port :     USB port
    Buttons (8)
      Type     Name               Multiplier
      button    Trigger             -
      button    Thumb               -
      button    Thumb 2             -
      button    Top                 -
      button    Top 2               -
      button    Pinkie              -
      button    Base                -
      button    Base 2              -
    Sliders (2)
      Type     Name               Multiplier     Tolerance
      slider    x                   1.0            0.0            absolute
      slider    y                   1.0            0.0            absolute
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ========================================================================

あるいは、以下のように適当な名前をつけておくというのもひとつの手です。

My GamePad Configuration
X_POS   X position   3  SLIDER  yoko     0  1.0  0.15
Y_POS   Y Position   3  SLIDER  tate     0  1.0  0.15
B_0     Button 0     1  BUTTON  foo      0  0.0  0.0
B_1     BUtton 1     1  BUTTON  bar      0  0.0  0.0

この状態でスケッチを実行すると、こんな具合の設定画面が表示され、

f:id:hoshi_sano:20140612024353j:plain

設定ファイルから特定できなかったボタンの設定をGUIで行うことが出来ます。
ゲームパッドのボタンをぽちぽち押すと、画面上で押したボタンに対応する箇所がチカチカ光るので、それを確認しながら設定を行います。

f:id:hoshi_sano:20140612024357j:plain

ひととおり設定が完了したら「USE」ボタンをクリック。適当に作成した設定ファイルに上書きする形で、GUIで指定した設定ファイルが生成されます。

6番目: 乗数

主にスライダーに設定するもののようです。例えばジョイスティックがあるデバイスの場合、乗数に1を設定した状態で右方向にスティックを倒しきるとgetValue()時に1が取得でき、反対に左方向にスティックを倒しきると-1が取得できます。
乗数に10を設定すると、右方向に倒しきって10、左方向に倒しきって-10、右方向に半分だけ倒すと5、左方向に半分だけ倒すと-5、といった具合になります。ゲームの主人公の移動速度をスティックの倒し具合で調整したい場合などに、ここの値を調整することになりそうです。

ちなみに僕が買ったゲームパッドでは十字キーの押し加減によるアナログ判定機能はなかっため、中間値の取得は出来ませんでした。0か1とか、0か10だけ。残念。

7番目: トレランス(許容値)

これも主にスライダーに設定するもののようです。ある一定量の入力があった場合以外は、入力を無視するための設定値です。例えば0.5を設定した場合、ジョイスティックを半分以上傾けないと入力があったとはみなされません。0.1など小さめの値を設定しておいて、微妙な入力による誤作動を防ぐなどの用途があるものと思われます。

使用例

設定ファイル:

My GamePad Configuration
X_POS	X position	3	SLIDER	x	0	1.0	0.0
Y_POS	Y Position	3	SLIDER	y	0	1.0	0.0
B_0	Buttton 0	1	BUTTON	Trigger	0	0.0	0.0

ソースコード:

import org.gamecontrolplus.*;

ControlIO control;
ControlDevice device;

ControlButton button;
ControlSlider[] sliders = new ControlSlider[2];

void setup() {
  control = ControlIO.getInstance(this);
  device = control.getMatchedDevice("gamepad_config");

  button = device.getButton("B_0");
  sliders[0] = device.getSlider("X_POS");
  sliders[1] = device.getSlider("Y_POS");
}

void draw() {
  // Triggerボタンを押すと、その旨を表示
  if (button.pressed()) println("Button 0 Pressed");

  // 十字キー(横)を押すと、その旨と押した方向の値を表示
  float x_value = sliders[0].getValue();
  if (abs(x_value) > 0) println("X_POS Pressed:", x_value);

  // 十字キー(縦)を押すと、その旨と押した方向の値を表示
  float y_value = sliders[1].getValue();
  if (abs(y_value) > 0) println("Y_POS Pressed:", y_value);
}