/**
* inputGamepa
* @class
* @classdesc
* Gamepad APIを利用してゲームパッドの入力を管理します。<br\
* 方向キー、各種ボタン、アナログスティックの状態を検出し、<br\
* ゲームで利用可能なプロパティとして提供します。
*/
class inputGamepad {
constructor() {
let support = (window.Gamepad); //Support Gamepad API
let connect = (navigator.getGamepads); //GamePad Ready
let gamepad_list; // = navigator.getGamepads();
this.upkey; // = false;
this.downkey; // = false;
this.leftkey = false;
this.rightkey = false;
this.btn_start = false;
this.btn_back = false;
this.btn_lb = false;
this.btn_rb = false;
this.btn_lt = false;
this.btn_rt = false;
this.btn_l3 = false;
this.btn_r3 = false;
this.btn_a = false;
this.btn_b = false;
this.btn_x = false;
this.btn_y = false;
this.r; //-1:off 0-360:input_r leftstick
this.ls_x; //axes[0]
this.ls_y; //axes[1]
this.rs_x; //axes[2]
this.rs_y; //axes[3]
let readystate = false;
this.button;
this.axes;
/**
* @method
* @returns {boolean} ゲームパッド接続状態
* @description
* ゲームパッドの接続状態を確認し、その入力状態を更新します。 <br\
* Gamepad APIがサポートされており、ゲームパッドが認識されている場合に、<br\
* 最新のボタンやスティックの入力を取得します。
*/
this.check = function () {
readystate = false;
if (!(support && connect)) return false;
gamepad_list = navigator.getGamepads();
//connect Check 認識したうちで一番若い番号のコントローラを使用する
let ct = []; for (let i in gamepad_list) if (Boolean(gamepad_list[i])) ct.push(i);
let num = Math.min(...ct);
let gamepad = gamepad_list[num];
if (!gamepad) return false;
readystate = true;
this.update(gamepad);
return readystate;
};
/**
* @typedef {object} Gamepad Gamepadオブジェクト
* @see https://developer.mozilla.org/ja/docs/Web/API/Gamepad
*/
//↓これは基本外部から使用しない↓
//差し替えでGamepadのハード別対応させることが出来る。
/**
* @method
* @param {Gamepad} gamepad Gamepadオブジェクト
* @description
* ゲームパッドからの生データ(ボタンや軸の値)を受け取り、<br\
* 内部の入力状態プロパティを更新します。<br\
* 通常は`check`メソッドによって内部的に呼び出され<br\
* 特定のハードウェアマッピングに対応できます。
* @todo ハードウェアマッピングの設定切り替え操作
*/
this.update = function (gamepad) {
//paramater:
//Logicool Gamepad F310 (Mode *DirectX/X-Input) ------
//id: "Logicool Dual Action (STANDARD GAMEPAD Vendor: 046d Product: c216)"
//mapping: "standard"
var p = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
//id: "Xbox 360 Controller (XInput STANDARD GAMEPAD)"
//mapping: "standard"
//var p = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
//
//SONY CUH-ZCT2J WIRELESS CONTROLLER (PS4Pro) ------
//id: "Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc)"
//mapping: "standard"
//var p = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
//
//SONY CFI-ZCT1J WIRELESS CONTROLLER (PS5) ------
//id: "DualSense Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 0ce6)"
//mapping: "standard"
//var p = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
var button = gamepad.buttons;
var axes = gamepad.axes;
this.button = button;
this.axes = axes;
this.upkey = (Boolean(button[p[12]])) ? button[p[12]].pressed : false;
this.downkey = (Boolean(button[p[13]])) ? button[p[13]].pressed : false;
this.leftkey = (Boolean(button[p[14]])) ? button[p[14]].pressed : false;
this.rightkey = (Boolean(button[p[15]])) ? button[p[15]].pressed : false;
this.btn_start = (Boolean(button[p[9]])) ? button[p[9]].pressed : false;
this.btn_back = (Boolean(button[p[8]])) ? button[p[8]].pressed : false;
this.btn_lb = (Boolean(button[p[4]])) ? button[p[4]].pressed : false;
this.btn_rb = (Boolean(button[p[5]])) ? button[p[5]].pressed : false;
this.btn_lt = (Boolean(button[p[6]])) ? button[p[6]].pressed : false;
this.btn_rt = (Boolean(button[p[7]])) ? button[p[7]].pressed : false;
this.btn_l3 = (Boolean(button[p[10]])) ? button[p[10]].pressed : false;
this.btn_r3 = (Boolean(button[p[11]])) ? button[p[11]].pressed : false;
this.btn_a = (Boolean(button[p[0]])) ? button[p[0]].pressed : false;
this.btn_b = (Boolean(button[p[1]])) ? button[p[1]].pressed : false;
this.btn_x = (Boolean(button[p[2]])) ? button[p[2]].pressed : false;
this.btn_y = (Boolean(button[p[3]])) ? button[p[3]].pressed : false;
this.ls_x = (Boolean(axes[0])) ? axes[0] : 0;
this.ls_y = (Boolean(axes[1])) ? axes[1] : 0;
this.rs_x = (Boolean(axes[2])) ? axes[2] : 0;
this.rs_y = (Boolean(axes[3])) ? axes[3] : 0;
var x = Math.floor(axes[0] * 100); //> 0.05)?axes[j]:0;
var y = Math.floor(axes[1] * 100); //> 0.05)?axes[j+1]:0;
this.r = ((Math.abs(x) < 10) && (Math.abs(y) < 10)) ? -1 : target_r(x * 100, y * 100);
return;
};
function target_r(wx, wy) {
var r = (wx == 0) ?
((wy >= 0) ? 180 : 0) :
((Math.atan(wy / wx) * (180.0 / Math.PI)) + ((wx >= 0) ? 90 : 270));
return r;
}
/**
* @method
* @returns {string[]} 状態情報テキストリスト
* @description
* 接続されているゲームパッドの識別の詳細情報と、<br\
* 現在のボタン、スティックの入力状態をテキストリストで返します。<br\
* デバッグやゲームパッドの動作確認に役立ちます。
*/
this.infodraw = function () {
let str = [];
str.push("[Gamepad] max:" + gamepad_list.length);
//Coneect Check
let ct = [];
for (let i in gamepad_list) {
if (Boolean(gamepad_list[i])) {
str.push("no:" + i + ", type:" + gamepad_list[i].mapping);
str.push("id:" + gamepad_list[i].id);
//console.log("no:" + i + ", type:" + gamepad_list[i].mapping);
//console.log("id:" + gamepad_list[i].id);
ct.push(i);
} else {
str.push("no." + i + " not Connect");
}
}
str.push("--------------------------------");
let num = Math.min(...ct);
if (gamepad_list[num]) {
// ------------------------------------------------------------
// Gamepad オブジェクト
// ------------------------------------------------------------
// ゲームパッドリストを取得する
// gamepad_list = navigator.getGamepads();
// ゲームパッドリスト内のアイテム総数を取得する
// num = gamepad_list.length;
// gamepad[num]
// ------------------------------------------------------------
// タイムスタンプ情報 // gamepad.timestamp
// ------------------------------------------------------------
// ゲームパッドの識別名 // gamepad.id
// ------------------------------------------------------------
// ゲームパッドの物理的な接続状態 // gamepad.connected
// ------------------------------------------------------------
// マッピングタイプ情報 // gamepad.mapping
// ------------------------------------------------------------
// ボタンリスト // gamepad.buttons[] // buttons.length;
// ------------------------------------------------------------
// 軸リスト // gamepad.axes[]; //// axes.length;
let gp = gamepad_list[num];
str.push("Use No:" + num + ", type:" + gp.mapping);
str.push("id:" + gp.id);
str.push("");
str.push("Up [" + (this.upkey ? "o" : "-") + "]"
+ " Down [" + (this.downkey ? "o" : "-") + "]"
+ " Left [" + (this.leftkey ? "o" : "-") + "]"
+ " Right[" + (this.rightkey ? "o" : "-") + "]");
str.push("");
str.push("(A) [" + (this.btn_a ? "o" : "-") + "]"
+ " (B) [" + (this.btn_b ? "o" : "-") + "]"
+ " (X) [" + (this.btn_x ? "o" : "-") + "]"
+ " (Y) [" + (this.btn_y ? "o" : "-") + "]");
str.push("");
str.push("BACK [" + (this.btn_back ? "o" : "-") + "]"
+ " START[" + (this.btn_start ? "o" : "-") + "]");
str.push("LB [" + (this.btn_lb ? "o" : "-") + "]"
+ " RB [" + (this.btn_rb ? "o" : "-") + "]");
str.push("LT [" + (this.btn_lt ? "o" : "-") + "]"
+ " RT [" + (this.btn_rt ? "o" : "-") + "]");
str.push("L3 [" + (this.btn_l3 ? "o" : "-") + "]"
+ " R3 [" + (this.btn_r3 ? "o" : "-") + "]");
str.push("");
str.push("r = " + this.r);
str.push("");
str.push("Ls_x: " + this.ls_x);
str.push("Ls_y: " + this.ls_y);
str.push("Rs_x: " + this.rs_x);
str.push("Rs_y: " + this.rs_y);
} else {
str.push("Not Ready.");
}
return str;
};
}
}