Gamepad APIを研究して入力部分を作り直す

公開:2017-12-03 09:25
更新:2020-02-15 04:37
カテゴリ:シューティングゲーム,ゲーム製作,HTML5,ES6,JS,Blender

もう12月か。。

4月からシューティングゲームを作ると宣言してはや8か月が経過している。

シューティングゲームばかりやっていたわけではなく、はてなブログの引っ越しとか、Overpass APIをいじっていたりしてたりとかしてたから、実質いじっている時間はトータルすると1か月も満たないかもしれない。 だけど遅々として進まないのはいつもの通り。でも最近は割と集中してコードを書いている。なのでBlog更新は滞りがちである。。

先日、気になっていた入力部分のコードを書き直した。見直すとかなりいい加減だし、キーカスタマイズができるような作りになっていなかったので。 さらにChrome以外の他のブラウザで動かすと、自機のコントロールができないという問題があったのだ。

それで、Gamepad APIの仕様を見直しつつ、作り直すことにした。本当は、配置エディタを作ったり、Blenderでキャラクターを作ったりしたいのだが、気になってしょうがないので先に手を付けることにしたのだ。

入力機器の検証は都合3台のゲームパッドを使用した。2台はXInput対応のもの(ELECOM JC-U3613M,ホリ FIGHTING STICK EX2)、もう1つはPS3用(ホリ RAP 隼)のものである。このシューティングゲームを作るために、ゲーセンタイプのコントローラ(中古)を2台購入したのだけれど、結論から言うと少なくともWindows 10の環境ではXInput対応ゲームパッドを使用するのが無難だということがわかった。

https://sfpgmr.github.io/images/2017/12/2017120201.jpg

Gamepad API

Gamepad APIはゲームパッドの入力をスクリプトで受け取るためのDOM APIで、2017/12/3現在もドラフトのステータスである。Chrome/Firefox/Edgeすべてが対応しているので、おそらく近い将来Recommendになるのではないだろうかと思うが。

Gamepad(W3C)

ドラフトの状態ではあるが、MDNなどでもすでに詳細な解説が載っているところからすると、各ベンダとも力が入っている規格案なのではないかと思う。ゲームは普及のキラーコンテンツになるからね。Windowsが普及したのも、過去ゲームの互換性維持とゲーム開発のAPIを早くから用意・拡充したことも要因のひとつだと思う。

上記を読めば大抵のことがわかり、実装できると思う。が、ちょっと気になる部分があるので、備忘録代わりに書いておくことにする。 ここから先は、上記2つのドキュメントを読み、理解していることを前提とする。

Gamepad APIの検証ページはすでにいくつかあってこのページによって持っているゲームパッドが動作するかどうかを試すことができる。

  1. HTML5 Gamepad Tester
  2. luser.github.io/gamepadtest/
  3. internetexplorer.github.io/Gamepad-Sample/

ただ2.については動作がちょっと怪しい。1.か3.でチェックするのがよいと思う。

上記サイトでチェックした結果、私が持っている3種のゲームパッドのうち、Chrome・Firefox・Edgeですべて利用できるのはELECOM JC-U3613Mだけであった。このゲームパッドはXBOX 360ゲームパッド互換である。

ブラウザ ホリ FIGHTING STICK EX2 ELECOM JC-U3613M ホリ RAP 隼
OS上 XBox360 Controller For Windows XBox360 Controller For Windows HID準拠ゲームコントローラー
ブラウザ上で認識されるGamepadID      
Chrome Xbox 360 Controller (XInput STANDARD ARCADE_STICK) Xbox 360 Controller (XInput STANDARD GAMEPAD) RAP.N3 (Vendor: 0f0d Product: 003d)
Firefox xinput xinput 0f0d-003d-RAP.N3
Edge 認識なし Xbox 360 Controller (XInput STANDARD GAMEPAD) 認識なし
ブラウザ上で認識されるGamepadMappingType      
Chrome "standard" "standard" (空文字列)
Firefox "standard" "standard" (空文字列)
Edge - "standard" -

どうもEdgeはXBox360フルスペック対応でないと、ゲームパッドとして認めてくれないようである。ホリのはちょっとボタンが少ないから、フルスペックではないため認識しないのだろうと推測している。この件はIssueとして挙がっている。

Gamepad API only supports Xbox controllers - Microsoft Edge Development

しかし対応の予定は今のところないようである。とりあえずコメントに何とかしてくれと入れておいたが。。

Chrome/Firefoxはすべて認識しているところがすごいが、ただPS3のゲームパッドの認識には問題があった。実はホリ RAP 隼の方向スティック(POVもしくはハットスイッチともいうらしい)の認識が、ChromeとFirefoxでは異なるのである。

Chromeではホリ RAP 隼の方向スティックは、axes[9]で認識され、方向キーを動かした結果がすべてこのaxes[9]の値として入る。そして、どの方向に傾けたかを検出するには以下の計算でデコードする必要がある。

let dir = ( axes[9] + 1) * 7 / 2 + 0.5) | 0

デコードした結果、dirには真上にレバーを倒した状態を始点として、時計回りに0-7の値が入る。

Firefoxはaxes[4]~axes[7]に値が入るaxes[4]が右、axes[5]が左、axes[6]が上、axes[7]が下である。既定値は-1となっており、その方向にレバーを倒すとおのおのの値が1.0になる。

どちらかといえば、Firefoxの実装のほうが良いと思う。でもそもそもaxes(軸)はアナログスティック用なので、buttonにアサインしてほしいところだが。。さらに言うと得られるIDの値も違うため、クロスブラウザでホリ RAP 隼をサポートするのはちょっと面倒かなぁと。

このaxesとbuttonsの配置については規格案では標準的なGamepadMappingTypeとして"standard"を用意している。

https://www.w3.org/TR/gamepad/standard_gamepad.svg

ベンダは各デバイスを上記の配置にソフトウェア的に再配置することが推奨されている。

実装

実装するにあたっては、以下の要件で行うことにした。2Dスクロール・シューティングゲームという大前提はもちろんある。

これをベースに現在実装中のものが以下である。

ソースコード

動作サンプル

新しいウィンドウで開く

ソースコード・リソース

/dev/shooting3/devver/20171202/css/style.css

/dev/shooting3/devver/20171202/index.html

/dev/shooting3/devver/20171202/js/bundle.js

/dev/shooting3/devver/20171202/js/dsp.js