あたごんとFlash-as3isolib


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


今回は、好きな画像をas3isolibで扱う方法について説明します。

好きな画像を表示させるために、as3isolibでは専用のクラス、IsoSpriteクラスが用意されています。
早速、ゲーム界で世界一有名な次の画像を、as3isolib上に表示させてみましょう。

あたごんとFlash-まりお

package
{
    import as3isolib.display.IsoSprite;
    import as3isolib.display.scene.IsoGrid;
    import as3isolib.display.scene.IsoScene;
    
    import flash.display.Bitmap;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.net.URLRequest;
    
    public class IsoSpriteSample extends Sprite
    {
        private var _isoScene:IsoScene;

        public function IsoSpriteSample()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;

            // シーンを作る
            _isoScene = new IsoScene();
            // displayListと繋ぐ
            _isoScene.hostContainer = this;

            // 分かりにくいのでおなじみのグリッドも追加
            var grid:IsoGrid = new IsoGrid();
            grid.cellSize = 16;
            _isoScene.addChild( grid );
            
            /*
            * 外部画像をロードしてセット
            */
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener( Event.COMPLETE, _setImage );
            loader.load( new URLRequest( "./images/mario.gif" ) );

            function _setImage( e:Event ):void
            {
                // ロードした画像をセット
                var marioImage:Bitmap = e.target.content;
                // マリオの足下がグリッドの座標と一致するように修正
                marioImage.x = -marioImage.width/2;
                marioImage.y = -marioImage.height;

                var isoSprite:IsoSprite = new IsoSprite();
                // spritesに表示したい画像をセット
                isoSprite.sprites = [ marioImage ];
                isoSprite.x = 16;
                isoSprite.y = 16;
                // シーンに追加
                _isoScene.addChild( isoSprite );

                // レンダリング
                _isoScene.render();
            }
        }
    }
}
あたごんとFlash-まりおさん表示

IsoSpriteのspritesに画像を配列で指定するだけです。とてもシンプル。
DisplayObjectであればMovieClipでも何でもOKです。
 
例えば、次の3つの画像とマリオさんを使うと、こんなものが作れちゃいます。

あたごんとFlash-床ブロック あたごんとFlash-?ブロック あたごんとFlash-普通のブロック あたごんとFlash-まりお

あたごんとFlash-gridmario
クリックするとマリオさんが動くようになっているのですが、Flashを貼り付けられないので、実際に動くサンプルが見たい方は、「コチラ 」の同じ内容のブログをご覧になって下さい。




少し長くなりますが、ソースはこんな感じです。マリオ移動のために、有名なGTween というTweenライブラリを利用しています。

package
{
    import as3isolib.core.ClassFactory;
    import as3isolib.core.IsoDisplayObject;
    import as3isolib.display.IsoSprite;
    import as3isolib.display.renderers.DefaultShadowRenderer;
    import as3isolib.display.scene.IsoGrid;
    import as3isolib.display.scene.IsoScene;
    import as3isolib.geom.IsoMath;
    import as3isolib.geom.Pt;
    
    import com.gskinner.motion.GTween;
    import com.gskinner.motion.GTweener;
    
    import eDpLib.events.ProxyEvent;
    
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    
    public class IsoSpriteSample2 extends Sprite
    {
        private const GRID_SIZE:int = 16;
        private var _mario:IsoSprite;
        private var _isoScene:IsoScene;
        
        public function IsoSpriteSample2()
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;

            // シーンを作る
            _isoScene = new IsoScene();
            // displayListと繋ぐ
            _isoScene.hostContainer = this;
            // 見切れちゃうので、全体の表示位置をちょっとずらず
            x = 120;
            y = 50;
            
            _mario = new IsoSprite();
            /*
             * Flashで作ってswcに入れたMovieClipをセット
             */
            // マリオさん
            var marioImage:MovieClip = new Mario();
            marioImage.y = GRID_SIZE/2;
            _mario.sprites = [ marioImage ];
            _mario.width = GRID_SIZE;
            _mario.length = GRID_SIZE;
            _mario.height = GRID_SIZE*2;
            _mario.x = GRID_SIZE*3;
            _mario.y = GRID_SIZE*3;
            _mario.z = GRID_SIZE*1;
            _isoScene.addChild( _mario );
            
            /*
             * 5x5の床を敷き詰める
             */
            for ( var i:int = 0; i < 7; i++ )
            {
                for ( var j:int = 0; j < 7; j++ )
                {
                    var isoGroundBlock:IsoSprite = _createBlock( "groundBlock", GRID_SIZE*i, GRID_SIZE*j, 0 );
                    _isoScene.addChild( isoGroundBlock );
                }
            }
            
            /*
             * 1-1のブロック配置を再現
             */
            var blockBitmapData:BitmapData = new Block(0,0);
            var questionBlockBitmapData:BitmapData = new QuestionBlock(0,0);

            // ブロック1
            var isoBlock1:IsoSprite = _createBlock( "block", GRID_SIZE*1, GRID_SIZE*3, GRID_SIZE*4 );
            _isoScene.addChild( isoBlock1 );
            
            // ?ブロック1
            var isoQuestionBlock1:IsoSprite = _createBlock( "questionBlock", GRID_SIZE*2, GRID_SIZE*3, GRID_SIZE*4 );
            _isoScene.addChild( isoQuestionBlock1 );
            
            // ブロック2
            var isoBlock2:IsoSprite = _createBlock( "block", GRID_SIZE*3, GRID_SIZE*3, GRID_SIZE*4 );
            _isoScene.addChild( isoBlock2 );

            // ?ブロック2
            var isoQuestionBlock2:IsoSprite = _createBlock( "questionBlock", GRID_SIZE*4, GRID_SIZE*3, GRID_SIZE*4 );
            _isoScene.addChild( isoQuestionBlock2 );

            // ブロック3
            var isoBlock3:IsoSprite = _createBlock( "block", GRID_SIZE*5, GRID_SIZE*3, GRID_SIZE*4 );
            _isoScene.addChild( isoBlock3 );
            
            // 表示
            _isoScene.render();
            
            // クリックしたところへマリオを移動させる
            addEventListener( MouseEvent.CLICK, _moveMario );
        }
        
        private function _createBlock( type:String, x:int, y:int, z:int ):IsoSprite
        {
            var image:BitmapData;
            switch ( type )
            {
                case "block":
                    image = new Block( 0, 0 );
                    break;
                case "questionBlock":
                    image = new QuestionBlock( 0, 0 );
                    break;
                case "groundBlock":
                    image = new GroundBlock( 0, 0 );
                    break;
            }

            // 画像を作って、グリッドに合わせて真ん中にする
            var bitmap:Bitmap = new Bitmap( image );
            bitmap.x = -bitmap.width/2;
            bitmap.y = -bitmap.height/2;

            var isoBlock:IsoSprite = new IsoSprite();
            isoBlock.width = GRID_SIZE;
            isoBlock.length = GRID_SIZE;
            isoBlock.height = GRID_SIZE;
            isoBlock.sprites = [ bitmap ];
            isoBlock.x = x;
            isoBlock.y = y;
            isoBlock.z = z;
            
            return isoBlock;
        }

        private function _moveMario( e:MouseEvent ):void
        {
            // 見切れるのを直した分を考慮して、クリック座標を計算する
            var clickPos:Point = new Point( e.stageX-120, e.stageY-50 );
            // 目的地の極座標を、グリッド座標に変換する
            var destPt:Pt = new Pt( clickPos.x, clickPos.y+GRID_SIZE/2 );
            IsoMath.screenToIso( destPt );
            
            // フィールドの外をクリックした場合は無視する
            if ( destPt.x > GRID_SIZE * 7 || destPt.y > GRID_SIZE * 7 )
            {
                return;
            }
            
            var distance:Number = Pt.distance( new Pt( _mario.x, _mario.y ), destPt );
            var mario:MovieClip = _mario.sprites[ 0 ];
            mario.gotoAndPlay( "run" );

            // マリオのグリッド座標を、極座標に変換する
            var marioPt:Pt = new Pt( _mario.x, _mario.y );
            IsoMath.isoToScreen( marioPt );
            mario.scaleX = (clickPos.x - marioPt.x)/Math.abs(clickPos.x - marioPt.x);

            // 実行済みのtweenをキャンセルする
            GTweener.removeTweens( _mario );
            // 目的地までマリオをtweenさせる
            GTweener.to( _mario, distance/(GRID_SIZE*6), { "x":destPt.x, "y":destPt.y }, { onChange:_render, onComplete:_complete } );
        }

        private function _render( tween:GTween ):void
        {
            _isoScene.render();
        }
        
        private function _complete( tween:GTween ):void
        {
            var mario:MovieClip = _mario.sprites[ 0 ];
            mario.gotoAndPlay( "stop" );
        }
    }
}

なんとなく、アメーバぴぐっぽいものが作れそうな雰囲気がでてきました。ね?
 
 
以上で、IsoSpriteの説明は終了です!
次回は、フィルターについて書いてみたいと思います。