JavaScriptでゲーム作ろう

実はブラウザ上で動くブラウザゲームでもゲームパッドで遊ぶことができます。

というわけで今回はゲームパッドを使えるようにするやり方を紹介します。

 

なお、この記事は前回・前々回からの続きで入力操作3部作の最後となります。

プログラムは追加する形で出来ているので気になる方は前の2つの記事もぜひ読んでください。

キー入力操作

バーチャルパッド

 

この記事ではサンプルをベースにしたさっくりとした解説ですが、ゲームパッドAPIについてより詳しく知りたい方はこちらの記事が参考になります。

 

 

では、今回のサンプルプログラムはこちら

サンプルプログラムをプレイ

方向キー(または左スティック)で移動、Aボタン・Bボタンで弾発射、スタートボタンでポーズになってます。

 

ファイルをダウンロード

 

当然ながらゲームパッドが必要なのでちゃんとパソコンにつないで操作してください。

 

codepenにも投稿してみたので使ってみてください(スマホで見るとバーチャルパッドが表示されます)。

See the Pen
p94e.js操作サンプル
by いんわん (@inwan78)
on CodePen.

 

インプットマネージャーのプログラム本体はこっちに分けてあります。

See the Pen
JavaScrip操作入力管理プログラム【ゲーム開発】
by inwan (@inwan78)
on CodePen.

 

GamePadクラスのプログラム

ゲームパッドを扱うGamePadクラスのプログラムだけ載せておきます。

//ゲームパッドクラス
class GamePad {
  constructor(input){
    this.input = input;
    this.isConnected = false;
    this.isStickUsing = false;
  }
  connected(){
    this.isConnected = true;
  }
  disconnected(){
    this.isConnected = false;
  }
  update(){
    if(!this.isConnected) return;    
    const input = this.input;
    const pads = navigator.getGamepads();

    const sticks = pads[0].axes;
    //X軸
    if(sticks[0] > 0.5){
      input.keys.Right = true;
      this.isStickUsing = true;
    }else if(this.isStickUsing){
      input.keys.Right = false;
    }
    if(sticks[0] < -0.5){
      input.keys.Left = true;
      this.isStickUsing = true;
    }else if(this.isStickUsing){
      input.keys.Left = false;
    }
    //Y軸
    if(sticks[1] > 0.5){
      input.keys.Down = true;
      this.isStickUsing = true;
    }else if(this.isStickUsing){
      input.keys.Down = false;
    }
    if(sticks[1] < -0.5){
      input.keys.Up = true;
      this.isStickUsing = true;
    }else if(this.isStickUsing){
      input.keys.Up = false;
    }

    const buttons = pads[0].buttons;
    //上
    if(buttons[12].pressed){
      input.keys.Up = true;
      this.isStickUsing = false;
    }else if(!this.isStickUsing){
      input.keys.Up = false;
    }
    //下
    if(buttons[13].pressed){
      input.keys.Down = true;
      this.isStickUsing = false;
    }else if(!this.isStickUsing){
      input.keys.Down = false;
    }
    //左
    if(buttons[14].pressed){
      input.keys.Left = true;
      this.isStickUsing = false;
    }else if(!this.isStickUsing){
      input.keys.Left = false;
    }
    //右
    if(buttons[15].pressed){
      input.keys.Right = true;
      this.isStickUsing = false;
    }else if(!this.isStickUsing){
      input.keys.Right = false;
    }
    //スタート
    if(buttons[9].pressed){
      input.keys.Start = true;
    }else{
      input.keys.Start = false;
    }
    //A
    if(buttons[0].pressed){
      input.keys.A = true;
    }else{
      input.keys.A = false;
    }
    //B
    if(buttons[1].pressed){
      input.keys.B = true;
    }else{
      input.keys.B = false;
    }
  }
}

 

ゲームパッドの接続イベント

ゲームパッドは接続や切断時にイベントが発生します。

//ゲームパッド接続時のイベント
addEventListener("gamepadconnected", (e) => {
  //処理
});
//ゲームパッド切断時のイベント
addEventListener("gamepaddisconnected", (e) => {
  //処理
});

なので上記のように記述して接続時・切断時に必要な処理を記述します。

 

ゲームパッドの情報を取得

接続後、ゲームパッドの情報を取得するには

const pads = navigator.getGamepads();

と記述すれば取得できます。

そしてこれは複数ゲームパッドが接続されている可能性があるので配列になっています。

1つだけの場合はpads[0]に情報が入っています。

console.log(pads[0]);

で内容を確認できます。

 

ボタン類はpads[0].buttonsという配列に入っています。

  • 0・・・A
  • 1・・・B
  • 2・・・X
  • 3・・・Y
  • 4・・・L1
  • 5・・・R1
  • 6・・・L2
  • 7・・・R2
  • 8・・・SELECT
  • 9・・・START
  • 10・・左スティック押し込み
  • 11・・右スティック押し込み
  • 12・・上
  • 13・・右
  • 14・・下
  • 15・・左
  • 16・・xBoxボタン

押したかどうかの判定はpads[0].buttons[0].pressedに真偽値で入っているのでそれを使います。

 

スティックはpads[0].axes配列に入っています。

  • 0・・・左スティックのX軸(-1 ~ 1)
  • 1・・・左スティックのY軸(-1 ~ 1)
  • 2・・・右スティックのX軸(-1 ~ 1)
  • 3・・・右スティックのY軸(-1 ~ 1)

 

基本的にゲームパッドの使い方はこれだけです。

 

ゲームパッドクラスを作る

最後はゲームパッドクラスを作ってInputManagerに追加して入力操作プログラムを完成させるだけです。

 

と言っても特に特筆するようなところはほとんどないです。

サンプルプログラムを見てもらえばわかると思います。

 

気をつけないといけないところとしてはループ毎にnavigator.getGamepads()で情報を取得するところです。

ループ毎に取得しないと情報は更新されません。

 

クラスにupdate()メソッドを作っていますが、このクラスには自動更新機能は無いので必ずメインループ内に記述してください。

 

私のプログラムでは左スティックも十字キーと同じ4方向の入力にしか使っていません。

0.5以上(または-0.5以下)動かしたときに方向入力したと判断しています。

 

また、十字キーと左スティックを併用できるようにする場合も注意が必要です。

私のサンプルでは左スティックも十字キーと同じフラグを使用しているので塀用となるとうまく動いてくれません。

なのでどっちを使っているのかを判定するフラグを作ってチェックしています。

 

あと、スティックは指を離した状態できっちり0になりません。どちらかに少し傾いていたりします。

 

バーチャルパッドとの関係

激レアなことだとは思いつつ、スマホでゲームパッドを使う場合バーチャルパッドの表示は不要なので消えるようにしています。

接続時と切断時にvpadのdisplayを切り替えています(main.jsの205行目くらい)

//ゲームパッド接続時のイベント
addEventListener("gamepadconnected", (e) => {
  this.gamePad.connected();
  //バーチャルパッドがあったら(モバイルなら)非表示
  if(this.vpad){
    this.vpad.pad.style.display = "none";
  }
});
//ゲームパッド切断時のイベント
addEventListener("gamepaddisconnected", (e) => {
  this.gamePad.disconnected();
  //バーチャルパッドがあったら(モバイルなら)表示
  if(this.vpad){
    this.vpad.pad.style.display = "block";
  }
});

 

まとめ

以上で入力操作3部作終了です。

このサンプルプログラムでキー入力もバーチャルパッドもゲームパッドもすべて使えます。

A・Bボタン程度しか使っていませんが必要な場合はご自身で追加してください。

 

あと、ゲームはp94e.jsというので作っています。

サンプルもけっこう書いているのでぜひ見てみてください。