あたごんとFlash-as3isolib



さて、ActionScript3.0(as3)を使ってアイソメトリックな世界を簡単に作れるライブラリー「as3isolib」の解説3回目。
概要やインストール方法については解説第一回目を見てみてください。

今回は、「as3isobliでのEvent処理」について説明します。
Flashの貼り付け方が分からないので、実際のサンプルは外部ブログの同一記事を参考にしてください。すいません。

さっそく、箱を作って、ドラッグしてみます。
普通に書くとこうなると思います。



package
{
import as3isolib.core.IsoDisplayObject;
import as3isolib.display.primitive.IsoBox;
import as3isolib.display.scene.IsoScene;

import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;

public class IsoLibEventSample extends Sprite
{
private var _scene:IsoScene;
private var _box:IsoBox;
public function IsoLibEventSample()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

_scene = new IsoScene();
_scene.hostContainer = this;

// 箱を作る
_box = new IsoBox();
_box.x = 100;
_scene.addChild( _box );

// クリックイベントをセット 
_box.addEventListener( MouseEvent.MOUSE_DOWN, _dragEvent );
_box.addEventListener( MouseEvent.MOUSE_UP, _dragEvent );

// ドラッグ中、連続的に描画されるようにする
addEventListener( Event.ENTER_FRAME, _render );
}

private function _dragEvent( e:MouseEvent ):void
{
switch ( e.type )
{
case MouseEvent.MOUSE_DOWN:
e.currentTarget.startDrag();
break;
case MouseEvent.MOUSE_UP:
e.currentTarget.stopDrag();
break;
}
}

// 描画
private function _render( e:Event ):void
{
_scene.render();
}
}
}

あたごんとFlash-箱のドラッグ

しかし、箱をドラッグしてみると、次の様なエラーが起こってしまいます。

TypeError: Error #1034: 強制型変換に失敗しました。eDpLib.events::ProxyEvent@2c659f91 を flash.events.MouseEvent に変換できません。

勝手にMouseEventがProxyEventに書き換えられちゃいました。
 
実はas3isolibでは、イベントは全てProxyEventに変換されます。
この処理は、as3isolibのルートクラスとなるNodeクラスが継承しているEventDispatcherProxyが行っています。
この中で全てのイベントを1つの関数で全てハンドリングして、せっせとProxyEventを作って送り返しています。
興味がある人はソースをのぞいてみて下さい。イベントを伝達する仕組みが見れて興味深いです。
 
送られてくるProxyEventには3つのパラメータがあります。
 

・proxy:IEventDispatcher クリックされたIsoDisplayObject(ここでは箱)
・proxyTarget:IEventDispatcher クリックされたView要素(ここでは箱のグラフィック(Sprite))
・targetEvent:Event 本来ハンドリングしたかったイベント
 

それでは、これらを元にイベントハンドリング部分のソースを書き換えてみます。



// ProxyEventでハンドリングをする
private function _dragEvent( e:ProxyEvent ):void
{
// 本来送りたかったMouseEventとクリックを受け取った本体を取得する
var event:MouseEvent = e.targetEvent as MouseEvent;
var target:Sprite = e.proxyTarget as Sprite;

switch ( event.type )
{
case MouseEvent.MOUSE_DOWN:
target.startDrag();
break;
case MouseEvent.MOUSE_UP:
target.stopDrag();
break;
}
}



これで問題無くドラッグが出来るように見えます。
(※画像をクリックすると外部のブログの同一記事が開きます。動くサンプルがみたい人はどうぞ)
あたごんとFlash-箱のドラッグ
しかし、これでは、IsoBox(箱)を動かすのではなく、箱の中に入っているグラフィックだけを動かす事になってしまいます。traceしてみると、ドラッグしても、IsoBoxの座標は最初に設定した( 100, 0 )のままです。
そこで、IsoBox自体を動かすようにソースを書き換えてみます。



// _dragEventを書き換えて、新しく、_dragBoxを追加
private function _dragEvent( e:ProxyEvent ):void
{
var event:MouseEvent = e.targetEvent as MouseEvent;
switch ( event.type )
{
case MouseEvent.MOUSE_DOWN:
// ステージ上でのマウスの動きを追う
stage.addEventListener( MouseEvent.MOUSE_MOVE, _dragBox );
break;
case MouseEvent.MOUSE_UP:
stage.removeEventListener( MouseEvent.MOUSE_MOVE, _dragBox );
break;
}
}

private function _dragBox( e:MouseEvent ):void
{
_box.x = e.stageX;
_box.y = e.stageY;
}


(※画像をクリックすると外部のブログの同一記事が開きます。動くサンプルがみたい人はどうぞ)
あたごんとFlash-箱のドラッグ
分かりづらいですが、今度はちゃんとIsoBoxの座標が変わります。
しかし動きが変です。
これは、MouseEventから取得できる直交座標と、as3isolibで使われるグリッド座標が違うからです。
IsoMathクラスを使うと直交座標系を簡単にグリッド座標系に変換できるので、上で追加した_dragBoxメソッドを次の様に書き換えてみます。



private function _dragBox( e:MouseEvent ):void
{
// 直交座標系をグリッド座標系に変換する
// PtはPointクラスを継承した、as3isolibの座標系を表すためのクラス
// IsoMathはas3isolibでのグリッド座標系とFlashの直交座標系を行き来させるための計算クラス
var pt:Pt = new Pt( e.stageX, e.stageY );
IsoMath.screenToIso( pt );
_box.x = pt.x;
_box.y = pt.y;
}

(※画像をクリックすると外部のブログの同一記事が開きます。動くサンプルがみたい人はどうぞ)



あたごんとFlash-箱のドラッグ

ちゃんとドラッグできるようになりました。
こんな感じで他のイベントも問題無く処理ができると思います。
 
 
as3isolibのイベント処理の説明はこれでおしまいです!
次回は、表示を簡単にしてくれるIsoViewクラスについて説明したいと思います。