Flashでゲームパッドを使いたい。 Flex SDK 4.13をインストールでGamePad機能に対応するswfを作成できるようになった。 次は、GamePadを認識するActionScript3の書き方を学ぶ。
FlashでGamePadの動作確認は http://ics-web.jp/lab/archives/512 で可能だけどそのページにはソースがない。 Adobeの http://www.adobe.com/devnet/air/articles/game-controllers-on-air.html が参考になる。
サンプルどおりに組んでみるとこんな感じか。まずはゲームパッドを認識するところだけ。
Main.as
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.GameInputEvent;
import flash.ui.GameInput;
import flash.ui.GameInputDevice;
public class Main extends Sprite {
private var logger:Logger;
private var numPad:int;
private var gmInput:GameInput;
public function Main():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
logger = new Logger('Hello GameInput');
addChild(logger);
if ( ! GameInput.isSupported) return;
gmInput = new GameInput();
gmInput.addEventListener(GameInputEvent.DEVICE_ADDED, showLog);
gmInput.addEventListener(GameInputEvent.DEVICE_REMOVED, showLog);
showLog(null);
}
private function showLog(e:Event):void {
logger.log("GameInput.numDevices = " + GameInput.numDevices);
if (GameInput.numDevices <= 0) return;
for (var i:int = 0; i < GameInput.numDevices; i++ ) {
var device:GameInputDevice = GameInput.getDeviceAt(i);
logger.log("GameInput.getDeviceAt("+i+") = " + device);
if ( ! device) return;
logger.log(" device.enabled - " + device.enabled);
logger.log(" device.id - " + device.id);
logger.log(" device.name - " + device.name);
logger.log(" device.numControls - " + device.numControls);
logger.log(" device.sampleInterval - " + device.sampleInterval);
logger.log(" device.MAX_BUFFER - " + GameInputDevice.MAX_BUFFER_SIZE);
}
}
}
}Logger.as
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
public class Logger extends Sprite {
private var tf:TextField = new TextField();
private var lines:Array = [];
public function Logger(str:String) {
var fmt:TextFormat = new TextFormat('Courier New', 12, 0x333333);
tf.defaultTextFormat = fmt;
tf.autoSize = TextFieldAutoSize.LEFT;
tf.x = 10;
tf.y = 0;
tf.text = '';
addChild(tf);
log(str);
}
public function log(str:String):void {
lines.push(getTimeNow() + ' ' + str);
if (lines.length >= 40) lines.shift();
tf.text = lines.join('\n');
}
private function getTimeNow():String {
var dt:Date = new Date();
var h:String = ('0' + dt.getHours()).substr(-2);;
var m:String = ('0' + dt.getMinutes()).substr(-2);
var s:String = ('0' + dt.getSeconds()).substr( -2);
var ms:String = ('00' + dt.getMilliseconds()).substr(-3);
return h +':' + m +':' + s +'.' + ms;
}
public function clear():void {
lines = [];
}
}
}さて次はボタンの認識だ。
http://melancholy.raindrop.jp/wordpress/?p=88 の記事によると「GameInputDeviceのキャッシュ」は扱いが難しいらしい。 http://cuaoar.jp/2013/04/adobe-air-gameinput.html のサンプルコードはわかりやすかった。
以下は、Event.CHANGEで入力を取得している。ボタンを押すたび放すたびに変化するvalueを表示する。
Main.as
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.GameInputEvent;
import flash.ui.GameInput;
import flash.ui.GameInputControl;
import flash.ui.GameInputDevice;
public class Main extends Sprite {
private var logger:Logger;
private var numPad:int;
private var gmInput:GameInput;
public function Main():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
logger = new Logger('Hello GameInput');
addChild(logger);
if ( ! GameInput.isSupported) return;
gmInput = new GameInput();
gmInput.addEventListener(GameInputEvent.DEVICE_ADDED, showDevice);
gmInput.addEventListener(GameInputEvent.DEVICE_REMOVED, showDevice);
showDevice(null);
}
private function showDevice(e:Event):void {
logger.log("GameInput.numDevices = " + GameInput.numDevices);
if (GameInput.numDevices <= 0) return;
for (var i:int = 0; i < GameInput.numDevices; i++ ) {
var device:GameInputDevice = GameInput.getDeviceAt(i);
logger.log("GameInput.getDeviceAt("+i+") = " + device);
if ( ! device) return;
device.enabled = true;
logger.log(" device.enabled - " + device.enabled);
logger.log(" device.id - " + device.id);
logger.log(" device.name - " + device.name);
logger.log(" device.numControls - " + device.numControls);
for (var j:int = 0; j < device.numControls; j++) {
var control:GameInputControl = device.getControlAt(j);
logger.log(" control:id=" + control.id + ", value=" + control.value + " (" + control.minValue+" .. " + control.maxValue+")");
control.addEventListener(Event.CHANGE, showButtonStat);
}
}
}
private function showButtonStat(e:Event):void {
var control:GameInputControl = e.target as GameInputControl;
logger.log(" control:id=" + control.id + ", value=" + control.value + " (" + control.minValue+" .. " + control.maxValue+")");
}
}
}アナログスティックやトリガーの状態は小数値で取得できた。十字キー(D-PAD)やデジタルボタンは 1or0 で取得できる。
ところで振動はどう扱うんだろ。 http://www.adobe.com/devnet/air/native-extensions-for-air.html によるとAIR+ANE使えば使えるかも。でもWindows向けANEはないようだ。 Adobeは「Flashはゲーム分野をターゲットとする‥‥」というならvibrationに対応させてほしい。
exe化
Flashのswfを、Windowsのexeファイルに変換する方法に困った。
以前は http://www.adobe.com/jp/support/flashplayer/downloads.html の「Windows版Flash Player プロジェクター」をダウンロードして、その実行ファイルでswfを開き、[ファイル > プロジェクターを作成]でexe化できた。
しかし http://blawat2015.no-ip.com/~mieki256/diary/201308292.html によると FlashPlayer 11.3以降はexe化が不可になった。将来的に復活する予定もない。FlashPlayer 15で試したけど確かに不可だった。
ということは、FlashPlayer 11.8以上でしか動作しない「GamePad対応swf」はexe化できないじゃないかー。
製品のFlash CCでは http://cuaoar.jp/2013/12/flash-professional-cc-2.html http://helpx.adobe.com/jp/flash/using/exporting-projector-files.html にあるように「プロジェクター機能」を使ってexeを作成できるが、無料のFlex SDKだとAdobe AIRにするしかないようだ。
Adobe AIRは好きじゃない‥‥。exeじゃなくてインストーラーになるから動作確認が面倒だし、ビルド環境設定も面倒。 GamePad対応ゲームアプリは、無料で使えてexe化できるUnityで作ったほうがいいかも。


0 件のコメント:
コメントを投稿