【Windowsストアアプリ】 Xbox360コントローラーとCreateJSを連携させる(3)

前回に引き続きコードの解説をします。
前回のこのプロジェクトファイルをダウンロードしてなければダウンロードしてdefault.jsを開いてください。

default.jsを開くとapp.onactivated=function(){…
という箇所があります。
そこに初期化処理を書いています。

初期化以外の関数も紹介します。
・text – テキストを生成して返します。
・rect – 矩形を生成して返します。
・circle – 円を生成して返します。
・shoot – 緑の弾を生成して返します。
・renderLoop – 描画ごとに呼ばれます。

まず肝心のコントローラーの値がどうなってるのか見てみましょう。
renderLoop関数の中でコントローラの動きを逐一描画に反映しています。
controllerの状態を調べて接続されていればコントローラーの状態を
state.a、state.bのようにアクセスできます。

var state = controller.getState();

if (state.connected) {
...

値の種類はGameControllerプロジェクトのController.cppに列挙されています。

controllerState.connected = true;
controllerState.controllerId = m_index;
controllerState.packetNumber = m_xinputState.dwPacketNumber;
controllerState.LeftTrigger = m_xinputState.Gamepad.bLeftTrigger;
controllerState.RightTrigger = m_xinputState.Gamepad.bRightTrigger;
controllerState.LeftThumbX = m_xinputState.Gamepad.sThumbLX;
controllerState.LeftThumbY = m_xinputState.Gamepad.sThumbLY;
controllerState.RightThumbX = m_xinputState.Gamepad.sThumbRX;
controllerState.RightThumbY = m_xinputState.Gamepad.sThumbRY;

auto buttons = m_xinputState.Gamepad.wButtons;
controllerState.a = (buttons & XINPUT_GAMEPAD_A) != 0;
controllerState.b = (buttons & XINPUT_GAMEPAD_B) != 0;
controllerState.x = (buttons & XINPUT_GAMEPAD_X) != 0;
controllerState.y = (buttons & XINPUT_GAMEPAD_Y) != 0;
controllerState.dpad_up = (buttons & XINPUT_GAMEPAD_DPAD_UP) != 0;
controllerState.dpad_down = (buttons & XINPUT_GAMEPAD_DPAD_DOWN) != 0;
controllerState.dpad_left = (buttons & XINPUT_GAMEPAD_DPAD_LEFT) != 0;
controllerState.dpad_right = (buttons & XINPUT_GAMEPAD_DPAD_RIGHT) != 0;
controllerState.left_thumb = (buttons & XINPUT_GAMEPAD_LEFT_THUMB) != 0;
controllerState.right_thumb = (buttons & XINPUT_GAMEPAD_RIGHT_THUMB) != 0;
controllerState.left_shoulder = (buttons & XINPUT_GAMEPAD_LEFT_SHOULDER) != 0;
controllerState.right_shoulder = (buttons & XINPUT_GAMEPAD_RIGHT_SHOULDER) != 0;
controllerState.start = (buttons & XINPUT_GAMEPAD_START) != 0;
controllerState.back = (buttons & XINPUT_GAMEPAD_BACK) != 0;

コントローラーのAボタンを押したときは、登録されたイベントをdispatchEventで発行しています。

if (state.a) {
    btn_a.dispatchEvent('click');
    btn_a.alpha = 0.5;
} else {
    btn_a.alpha = 1;
}

イベントの登録は初期化時にaddEventListenerで行います。Aボタンを押すと弾が自機の前に描画されます。

     btn_a.addEventListener(
 "click",
 function (e) {
     console.log("ボタンをクリックしました a");
     _text.text = 'A';

     if (cnt < 59) {
         cnt++;
     } else {
         cnt = 0;
     }
     bulletarr[cnt].y = ship.y - 20;
     bulletarr[cnt].x = ship.x + 20;

     stage.addChild(bulletarr[cnt]);
     stage.update();
 }
 );

描画された弾は移動しないといけないのでrenderLoop関数の中に戻って見ます。
50pxずつ移動して画面の外側に出るとステージから弾の描画をremoveChildで消しています。

for (var i = 0; i < 60; i++) {
    if (bulletarr[i].y < -50) {
        stage.removeChild(bulletarr[i]);
    } else {
        bulletarr[i].y -= 50;
    }
};

では次に自機の動きですが、
画面内のエリアしか移動できないように制限してあります。
x2,y2で20をかけてありますが、数値を変えると移動量が変わります。画面の端まで行くと自機が隠れてしまうので自機のサイズ分40px引いています。

var x2 = Math.abs(state.leftThumbX) > 6500 ? x + (state.leftThumbX / 32767) * 20 : x;
var y2 = Math.abs(state.leftThumbY) > 6500 ? y - (state.leftThumbY / 32767) * 20 : y;

if (x2 < 0) {
    x2 = 0;
}
if (y2 < 0) {
    y2 = 0;
}
if (x2 > sketchSurface.width - 40) {
    x2 = sketchSurface.width - 40;
}
if (y2 > sketchSurface.height - 40) {
    y2 = sketchSurface.height - 40;
}

x = x2;
y = y2;
...
ship.x = x;
ship.y = y;

ループの最後で描画をアップデートします。

 stage.update(); 

描画のループは以上です。

ここからは初期化部分を見てみましょう
キャンバスのサイズを指定して、XY座標の初期化を行います。

sketchSurface.width = window.innerWidth;
sketchSurface.height = window.innerHeight;
x = sketchSurface.width / 2;
y = sketchSurface.height / 2;

描画のたびに弾を作ると画面が重くなってしまうので、描画スピードを落とさないように弾を60発ほど配列に準備します。

for (var i = 0; i < 60; i++) {
  bulletarr[i] = shoot();
}

CreateJSのステージにCanvasの要素はこれですと教えてあげます。

stage = new createjs.Stage('sketchSurface');

それから肝心のコントローラーの値をとる部分も必要ですね。(このデモでは1コンのみ値をとります。)

controller = new GameController.Controller(0);

画面に登場するものをステージに配置して、ボタンを押したときの振る舞いも設定してあげます。以下ボタンの数分繰り返します。

_rect_d.x = 100;
_rect_d.y = 200;
_rect_d.addEventListener(
       "click",
       function (e) {
           console.log("ボタンをクリックしました 下");
           _text.text = '下';
           ship.y += 20;
           stage.update();
       }
   );

各パーツをグループ化してステージに配置します。

var con1 = new createjs.Container();
var con2 = new createjs.Container();

con2.addChild(btn_a);
con2.addChild(btn_b);
con2.addChild(btn_x);
con2.addChild(btn_y);

con1.addChild(_rect_d);
con1.addChild(_rect_r);
con1.addChild(_rect_u);
con1.addChild(_rect_l);
con1.x = 100;
con1.y = 10;

con2.x = 1000;
con2.y = 50;
//ステージに配置
stage.addChild(con1);
stage.addChild(con2);

Canvasを1秒間に60回描画させてアニメーションをしてるように見せるので、描画のたびに呼び出される関数(renderLoop)を設定します。

 createjs.Ticker.addEventListener("tick", renderLoop);
 //フレームレート
 createjs.Ticker.setFPS(60);
 //requestAnimationFrameをON 
 createjs.Ticker.useRAF = true;

requestAnimationFrame参考:http://relishable.jp/createjs-ticker-useraf/

以上でコードの解説を終わります。
お疲れさまでした。

CreateJSのメソッドはドキュメントを参考ください
EaselJS v0.6.1 API Documentation : EaselJS

関連する記事:

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

名前 *