In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

SAVE THE EARTHをズルしてみた

インベーダーの侵略から地球を守りましょう。
* 
* 自機はマウスで操作可能です。
* 敵は自機で体当たりすると倒せます。
* 敵を倒すごとにENEMY LIFEゲージが減ります。
* ENEMY LIFEゲージが0にすればクリアです。
* 
* 敵が自機の後ろの地球にぶつかるとPLAYER LIFEゲージが減っていきます。
* PLAYER LIFEゲージが0になるとゲームオーバーです。
* 
* change Viewボタンで視点を変えれます。
* (難しくなるだけです。。)
* 
* インベーダーの描画のソースはnutsuさんのcheckmate作品より拝借しました。
* http://wonderfl.net/c/3OcH
* 
*
Get Adobe Flash player
by uwi 01 Aug 2010
/**
 * Copyright uwi ( http://wonderfl.net/user/uwi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/anmw
 */

// forked from sakusan393's SAVE THE EARTH
/*
 * 
 * インベーダーの侵略から地球を守りましょう。
 * 
 * 自機はマウスで操作可能です。
 * 敵は自機で体当たりすると倒せます。
 * 敵を倒すごとにENEMY LIFEゲージが減ります。
 * ENEMY LIFEゲージが0にすればクリアです。
 * 
 * 敵が自機の後ろの地球にぶつかるとPLAYER LIFEゲージが減っていきます。
 * PLAYER LIFEゲージが0になるとゲームオーバーです。
 * 
 * change Viewボタンで視点を変えれます。
 * (難しくなるだけです。。)
 * 
 * インベーダーの描画のソースはnutsuさんのcheckmate作品より拝借しました。
 * http://wonderfl.net/c/3OcH
 * 
 * */

package 
{
    import flash.display.BitmapData;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.display.Bitmap;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.net.navigateToURL;
    import flash.net.URLRequest;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.ui.Keyboard;
    import flash.utils.escapeMultiByte;
    import flash.utils.Timer;
    import net.hires.debug.Stats;
    import org.libspark.betweenas3.BetweenAS3;
    import org.libspark.betweenas3.easing.Expo;
    import org.papervision3d.core.geom.renderables.Particle;
    import org.papervision3d.materials.BitmapMaterial;
    import org.papervision3d.materials.ColorMaterial;
    import org.papervision3d.materials.special.ParticleMaterial;
    import org.papervision3d.materials.WireframeMaterial;
    import org.papervision3d.objects.primitives.PaperPlane;
    import org.papervision3d.objects.primitives.Plane;
    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.objects.special.ParticleField;
    import org.papervision3d.view.BasicView;
    
    [SWF(backgroundColor="0x000000", frameRate="30", width="465", height="465")]
    
    
    /**
     * ...
     * @author 393
     */
    public class Main extends BasicView
    {
        private var _count:int;
        private var _paperPlane:PaperPlane;
        private var _enemyArray:Array = new Array();
        private var _enemyGraArray:Array = new Array();
        private var _timer:Timer;
        private var _maxLength:int = 20;
        private var _isKeyLeft:Boolean;
        private var _isKeyRight:Boolean;
        private var _cMat:ColorMaterial;
        private var _wMat:WireframeMaterial;
        private var _particleField:ParticleField;
        private var _scoreTf:TextField;
        
        private var _hitCount:int;        
        private var _earth:Sphere;
        private var _damageCount:int;
        private var _viewAngleArray:Array = [0, 200, 800,-400];
        private var _viewAngleCount:int;
        private var _damageBm:Bitmap;
        private var _damageTimer:Timer;
        private var _scoreLabelTf:TextField;
        private var _playerLifeLabelTf:TextField;
        private var _playerLifeBar:Sprite;
        private var _restartBtnContainer:Sprite;
        private var _changeViewBtnContainer:Sprite;
        private var _tweetBtn:Sprite;
        private var _w:int;
        private var _h:int;
        private var _enemyLifeBar:Sprite;
        private var _enemyLifeLabelTf:TextField;
        private var _enemyPhisyc:int = 50;
        private var _playerPhisyc:int = 20;
        private var _messageLabelTf:TextField;
        private var _endTimer:Timer;
        private var _isCleared:Boolean = false;
        
        
        
        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);
            _w = stage.stageWidth;
            _h = stage.stageHeight;
            
            addChild(new Stats);
            
            //自機
            _cMat = new ColorMaterial(0xFFFF00);
            _cMat.doubleSided = true;
            _paperPlane = new PaperPlane(_cMat);
            scene.addChild(_paperPlane);
            _paperPlane.z = -100;
            _paperPlane.rotationZ = 180;
            
            camera.x = 0;
            camera.y = 0;
            camera.z = -1000;
            
            //母星
            var wireMat:WireframeMaterial = new WireframeMaterial();
            wireMat.doubleSided = true;
            _earth =  new Sphere(wireMat, 200, 8, 6);
            scene.addChild(_earth);
            _earth.z = -800;
            _earth.y = 0;
            
            //敵の生成
            for (var i:int = 0; i < _maxLength; i++)
            {
                //敵の色
                var color:int = Math.random() * 0xFFFFFF;
                color = color + 0xFF000000;
                //敵のグラフィック
                var bmd1:BitmapData = fig1(color);
                var bmdMat1:BitmapMaterial = new BitmapMaterial(bmd1);
                var bmd2:BitmapData = fig2(color);
                var bmdMat2:BitmapMaterial = new BitmapMaterial(bmd2);
                var bmd3:BitmapData = fig3(color);
                var bmdMat3:BitmapMaterial = new BitmapMaterial(bmd3);
                _enemyGraArray.push({gra1:bmdMat1,gra2:bmdMat2,gra3:bmdMat3});
                
                //敵を保持
                var enemy:Plane = new Plane(bmdMat1,180,180,0,0);
                _enemyArray.push(enemy);
                scene.addChild(_enemyArray[i]);
            }
            //敵の位置情報のセット
            initEnemy();
            
            //背景パーティクル
            var particle:ParticleMaterial = new ParticleMaterial(0xFFFFFF, 1, 1, 2);
            _particleField = new ParticleField(particle, 3000, 1, 1000, 5000, 5000)
            scene.addChild(_particleField);
            _particleField.y = -2000;
            
            //敵グラフィックのコマアニメ用
            var _timer:Timer = new Timer(250);
            _timer.addEventListener(TimerEvent.TIMER, changeEnemyGraphic);
            _timer.start();
            
            //クリア後のディレイ用タイマー
            _endTimer = new Timer(200,1);
            _endTimer.addEventListener(TimerEvent.TIMER, endTimerHandler);
            
            
            //score
            _scoreTf = createTf("0",20, "right", true);
            addChild(_scoreTf);
            _scoreTf.x = _w / 2 - _scoreTf.width / 2;
            _scoreTf.y = 10;
            
            //scoreLabel
            _scoreLabelTf = createTf("SCORE:",18, "right", false);
            addChild(_scoreLabelTf);
            _scoreLabelTf.x = _w / 2 - _scoreLabelTf.width;
            _scoreLabelTf.y = 13;
            
            //プレイヤーdamageLabel
            _playerLifeLabelTf = createTf("PLAYER LIFE:",18, "right", false);
            addChild(_playerLifeLabelTf);
            _playerLifeLabelTf.x = _w / 2 - _playerLifeLabelTf.width -100;
            _playerLifeLabelTf.y = 53;
            
            //プレイヤーライフバー
            _playerLifeBar = createLifeBar(0x00FF00);
            addChild(_playerLifeBar);
            _playerLifeBar.x = _w / 2 - _playerLifeBar.width / 2;
            _playerLifeBar.y = 56;
            
            //エネミーdamageLabel
            _enemyLifeLabelTf = createTf("ENEMY LIFE:",18, "right", false);
            addChild(_enemyLifeLabelTf);
            _enemyLifeLabelTf.x = _w / 2 - _enemyLifeLabelTf.width -100;
            _enemyLifeLabelTf.y = 83;

            //エネミーライフバー
            _enemyLifeBar= createLifeBar(0xFF9933);
            addChild(_enemyLifeBar);
            _enemyLifeBar.x = _w / 2 - _enemyLifeBar.width / 2;
            _enemyLifeBar.y = 86;
            
            //ダメージ演出
            var bmd:BitmapData = new BitmapData(_w, _h, false, 0xFFFF0000);
            _damageBm = new Bitmap(bmd);
            addChild(_damageBm);
            _damageBm.visible = false;
            _damageTimer = new Timer(50, 1);
            _damageTimer.addEventListener(TimerEvent.TIMER, damageTimerHandler);
            
            //リスタートボタン
            _restartBtnContainer = createBtn("restart");
            this.addChild(_restartBtnContainer);
            _restartBtnContainer.x = _w / 2 - _restartBtnContainer.width / 2;
            _restartBtnContainer.y = _h / 2 + 50;
            _restartBtnContainer.visible = false;
            _restartBtnContainer.addEventListener(MouseEvent.CLICK, restartHandler);
            
            //changeViewボタン
            _changeViewBtnContainer = createBtn("chage view");
            this.addChild(_changeViewBtnContainer);
            _changeViewBtnContainer.x = _w / 2 - _changeViewBtnContainer.width / 2;
            _changeViewBtnContainer.y = _h - _changeViewBtnContainer.height -10;
            _changeViewBtnContainer.addEventListener(MouseEvent.CLICK, changeViewHandler);
            
            //Tweetボタン
            _tweetBtn = createBtn("post twitter");
            this.addChild(_tweetBtn);
            _tweetBtn.x = _w / 2 - _restartBtnContainer.width / 2;
            _tweetBtn.y = _h / 2;
            _tweetBtn.visible = false;
            _tweetBtn.addEventListener(MouseEvent.CLICK, tweetHandler);
            
            //メッセージ
            _messageLabelTf = createTf("YOU LOSE!", 40, "center", false);
            _messageLabelTf.textColor = 0xFFFFFF;
            _messageLabelTf.width = 450;
            _messageLabelTf.visible = false;
            addChild(_messageLabelTf);
            _messageLabelTf.x = _w / 2 - _messageLabelTf.width / 2;
            _messageLabelTf.y = _h/2 - 80;

            
            //リサイズ判定
            stage.addEventListener(Event.RESIZE, resizeHandler);
            resizeHandler(null);
        }
        
        private function endTimerHandler(e:TimerEvent):void 
        {
            _restartBtnContainer.visible = true;
            _tweetBtn.visible = true;
            _messageLabelTf.text = "YOU WIN!";
            _messageLabelTf.visible = true;
            _enemyLifeBar.scaleX = 0;
            stopRendering();
        }
        //ライフバーの生成
        private function createLifeBar(color:int = 0xFFFFFF ):Sprite
        {
            var sp:Sprite = new Sprite();
            sp.graphics.beginFill(0xFF0000);
            var cover:Shape = new Shape();
            cover.graphics.beginFill(color);
            cover.graphics.drawRect(0, 0, 200, 20);
            cover.graphics.endFill();
            
            sp.addChild(cover);
            sp.graphics.drawRect(0, 0, 200, 20);
            sp.graphics.endFill();
            return sp;
        }
        
        private function tweetHandler(e:MouseEvent):void {
            var comment:String = "あなたは" + _hitCount + "匹のインベーダーを退治しました。あなたのおかげで";
            var comment1:String;
            if (!_isCleared)
            {
                comment1= "地球は滅亡しました [save the earth] ";
            }
            else
            {
                comment1= "地球は救われました [save the earth] ";                
            }
            var post:String = comment + comment1 + " " + "http://bit.ly/bZmfqp" + " " + "#wonderfl";
            navigateToURL(new URLRequest("http://twitter.com/home?status=" + escapeMultiByte(post)), "_blank");
        }
        //ボタンの生成
        private function createBtn(str:String):Sprite
        {
            var sp:Sprite = new Sprite();
            sp.buttonMode = true;
            var tf:TextField = createTf(str, 20, "center", true);
            tf.mouseEnabled = false;
            tf.background = true;
            tf.textColor = 0;
            tf.backgroundColor = 0xFFFFFF;
            sp.addChild(tf);
            return sp
        }
        
        //リサイズ処理
        private function resizeHandler(e:Event):void 
        {
            _w = stage.stageWidth;
            _h = stage.stageHeight;

            //ダメージ演出
            _damageBm.width = _w;
            _damageBm.height = _h;
            //各種座標
            _scoreTf.x = _w / 2 - _scoreTf.width / 2;
            _scoreLabelTf.x = _w / 2 - _scoreLabelTf.width-100;
            _playerLifeBar.x = _w / 2 - 200 / 2;
            _playerLifeLabelTf.x = _w / 2 - _playerLifeLabelTf.width -100;
            _enemyLifeBar.x = _w / 2 - 200 / 2;
            _enemyLifeLabelTf.x = _w / 2 - _playerLifeLabelTf.width -100;
            _restartBtnContainer.x = _w / 2 - _restartBtnContainer.width / 2;
            _restartBtnContainer.y = _h / 2 + 50;
            _changeViewBtnContainer.x = _w / 2 - _changeViewBtnContainer.width / 2;
            _changeViewBtnContainer.y = _h - _changeViewBtnContainer.height -10;
            _tweetBtn.x = _w / 2 - _restartBtnContainer.width / 2;
            _tweetBtn.y = _h / 2;
            _messageLabelTf.x = _w / 2 - _messageLabelTf.width / 2;
            _messageLabelTf.y = _h/2 - 80;

        }
        //リスタート処理
        private function restartHandler(e:MouseEvent):void 
        {
            _restartBtnContainer.visible = false;
            _messageLabelTf.visible = false;
            _tweetBtn.visible = false;
            initEnemy();
            _playerLifeBar.scaleX = 1;
            _enemyLifeBar.scaleX = 1;
            _damageCount = 0;
            _playerLifeBar.getChildAt(0).alpha = 1;
            _enemyLifeBar.getChildAt(0).alpha = 1;
            _scoreTf.text = "0";
            _count = 0;
            _hitCount = 0;
        }
        //初期化処理
        private function initEnemy():void
        {
            //敵の位置セット
            for (var i:int = 0; i < _maxLength; i++)
            {
                _enemyArray[i].z = 10000 + 1000 * i;
                _enemyArray[i].x = Math.random() * 100-200;
                _enemyArray[i].y = Math.random() * 100-200;
                _enemyArray[i].extra = { vx:Math.random() * 30 - 15,vy:Math.random() * 10 - 5, vz:Math.random() * 300 + 50,isBreak:false}
            }
            //PV3Dレンダリングスタート
            startRendering();
            //エンターフレーム処理
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
        
        //ダメージ演出用タイマー処理
        private function damageTimerHandler(e:TimerEvent):void 
        {
            _damageBm.visible = false;
        }
        private function createTf(str:String,size:int,tfmAlign:String,isBorder:Boolean):TextField 
        {
            var tf:TextField = new TextField();
            var tfm:TextFormat = new TextFormat();
            tfm.font = "Verdana";
            tfm.size = size;
            tfm.align = tfmAlign;
            tfm.color = 0xFFFFFF;
            tf.wordWrap = false;
            tf.border = isBorder;
            tf.borderColor = 0xFFFFFF;
            tf.defaultTextFormat = tfm;
            tf.text = str;
            tf.width = 200;
            tf.height = tf.textHeight + 3;
            
            return tf;
        }
        //カメラ視点の変化
        private function changeViewHandler(e:MouseEvent):void 
        {
            _viewAngleCount++;
            if (_viewAngleCount >= _viewAngleArray.length) _viewAngleCount = 0;
            var angle:int = _viewAngleArray[_viewAngleCount];
            trace("angle : " + angle);
            camera.y = angle;
        }
        //敵のグラフィックの変化
        private function changeEnemyGraphic(e:TimerEvent):void 
        {
            _count++;
            for (var i:int = 0; i < _maxLength; i++)
            {
                var bMat:BitmapMaterial;
                if (_count % 2 == 0) bMat = _enemyGraArray[i].gra1;
                else bMat = _enemyGraArray[i].gra2;
                if (!_enemyArray[i].extra.isBreak)
                {
                    _enemyArray[i].material = bMat;
                }
            }
        }
        
        //エンターフレーム処理
        private function enterFrameHandler(e:Event):void 
        {
            for (var i:int = 0; i < _maxLength; i++)
            {
                _enemyArray[i].z -= _enemyArray[i].extra.vz;
                _enemyArray[i].x += _enemyArray[i].extra.vx;
                _enemyArray[i].y += _enemyArray[i].extra.vy;
                //自機への当たり判定
                if (_paperPlane.hitTestObject(_enemyArray[i]))
                {
                    _enemyArray[i].material = _enemyGraArray[i].gra3;
                    _enemyArray[i].extra.isBreak = true;
                    _hitCount++;
                    _scoreTf.text = String(_hitCount);
                    trace("_scoreTf.text : " + _scoreTf.text);
                    var ePercent:Number = (_enemyPhisyc - _hitCount) / _enemyPhisyc;
                    _enemyLifeBar.scaleX = ePercent;
                    _enemyLifeBar.getChildAt(0).alpha = ePercent;
                    if (_enemyLifeBar.scaleX <= 0)
                    {
                        _isCleared = true;
                        removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
                        _endTimer.start();
                    }
                }
                //母星への当たり判定
                if (_earth.hitTestObject(_enemyArray[i]))
                {
                    trace("_damaged!! ");
                    if (!_enemyArray[i].extra.isBreak)
                    {
                        _damageCount++;
                        var pPercent:Number = (_playerPhisyc - _damageCount) / _playerPhisyc;
                        _playerLifeBar.scaleX = pPercent;
                        _playerLifeBar.getChildAt(0).alpha = pPercent;
                        trace("_damageCount : " + _damageCount);
                        _damageBm.visible = true;
                        _damageTimer.start();
                        
                        
                        //ダメージ0で終了
                        if (_playerLifeBar.scaleX <= 0)
                        {
                            _isCleared = false;
                            stopRendering();
                            removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
                            _restartBtnContainer.visible = true;
                            _tweetBtn.visible = true;
                            _messageLabelTf.text = "YOU LOSE..";
                            _messageLabelTf.visible = true;
                            _playerLifeBar.scaleX = 0;
                        }
                    }
                }
                //敵が画面外に消えた時の処理
                if (_enemyArray[i].z < -1000)
                {
                    _enemyArray[i].extra.isBreak = false;
                    _enemyArray[i].material = _enemyGraArray[i].gra1;
                    _enemyArray[i].z = 10000;
                    _enemyArray[i].x = Math.random() * 100 - 200;
                    _enemyArray[i].y = Math.random() * 100 - 200;
                    _enemyArray[i].extra = { vx:Math.random() * 30 - 15,vy:Math.random() * 20 - 10, vz:Math.random() * 300 + 50 }
                }
            }
            //自機のマウス操作
//            var vx:Number = ((mouseX - _w / 2) * 2 - _paperPlane.x) * 0.1;
//            var vy:Number = ((mouseY - _h/2)*2 - _paperPlane.y)*0.1;
            var v:Array = algo();
            var vx:Number = (v[0] - _paperPlane.x) * 0.1;
            var vy:Number = (v[1] - _paperPlane.y)*0.1;
            
            _paperPlane.x += vx;
            _paperPlane.y += vy;
             if (vx > 40) BetweenAS3.tween(_paperPlane, { rotationZ: 900 }, { rotationZ:900+720 } , 0.5, Expo.easeOut).play();
            else _paperPlane.rotationZ += (vx - _paperPlane.rotationZ) * 0.1+ 90;
            if (vx < -40) BetweenAS3.tween(_paperPlane, { rotationZ:900 }, { rotationZ:900-720 }, 0.5, Expo.easeOut).play();
            else _paperPlane.rotationZ += (vx - _paperPlane.rotationZ) * 0.1 + 90;
            //背景パーティクルの動き
            _particleField.rotationX -= 1;
            //母星の自転
            _earth.rotationY ++;
            
        }
        
        private function algo() : Array
        {
            // 敵機のうち、母星にぶつかる予定でかつ自機のz座標到達するまでの時間が最短のものを選ぶ
            var R : Number = 200 + 90 * Math.SQRT2;
            var mint : Number = 9999;
            var mini : int = -1;
            for (var i:int = 0; i < _maxLength; i++)
            {
                // 自機より後方は無視
                if(_enemyArray[i].z < -100)continue;
                
                var rx : Array = [_enemyArray[i].x, _enemyArray[i].y, _enemyArray[i].z + 800];
                var rv : Array = [_enemyArray[i].extra.vx, _enemyArray[i].extra.vy, -_enemyArray[i].extra.vz];
                // (x+vt)・v=0
                var rxv : Number = rx[0]*rv[0] + rx[1]*rv[1] + rx[2]*rv[2];
                var rvv : Number = rv[0]*rv[0] + rv[1]*rv[1] + rv[2]*rv[2];
                var t : Number = Math.max(-rxv / rvv, 0);
                var dClosest : Number =
                     (rx[0] + rv[0] * t) * (rx[0] + rv[0] * t) +
                     (rx[1] + rv[1] * t) * (rx[1] + rv[1] * t) +
                     (rx[2] + rv[2] * t) * (rx[2] + rv[2] * t);
                if(dClosest > R * R)continue;
                
                var ct : Number = (_enemyArray[i].z + 100) / _enemyArray[i].extra.vz;
                if(ct < mint){
                    mint = ct;
                    mini = i;
                }

            }
            
            if(mini == -1)return [0, 0];
            return [
                _enemyArray[mini].x + mint * _enemyArray[mini].extra.vx, 
                _enemyArray[mini].y + mint * _enemyArray[mini].extra.vy
                ];
        }
 
        
        public function fig1(color:int):BitmapData 
        {
        var highLignt:int = color;
         return BitmapPatternBuilder.build(
             [[0,0,1,0,0,0,0,0,1,0,0],
              [0,0,0,1,0,0,0,1,0,0,0],
              [0,0,1,1,1,1,1,1,1,0,0],
              [0,1,1,0,1,1,1,0,1,1,0],
              [1,1,1,1,1,1,1,1,1,1,1],
              [1,0,1,1,1,1,1,1,1,0,1],
              [1,0,1,0,0,0,0,0,1,0,1],
              [0,0,0,1,1,0,1,1,0,0,0]],
             [0x00000000, highLignt]);
        }    
        public function fig2(color:int):BitmapData
        {
            var highLignt:int = color;
             return BitmapPatternBuilder.build(
                 [[0,0,1,0,0,0,0,0,1,0,0],
                  [1,0,0,1,0,0,0,1,0,0,1],
                  [1,0,1,1,1,1,1,1,1,0,1],
                  [1,1,1,0,1,1,1,0,1,1,1],
                  [1,1,1,1,1,1,1,1,1,1,1],
                  [0,1,1,1,1,1,1,1,1,1,0],
                  [0,0,1,0,0,0,0,0,1,0,0],
                  [0,1,0,0,0,0,0,0,0,1,0]],
                 [0x00000000, highLignt])
        }
        public function fig3(color:int):BitmapData
        {
            var highLignt:int = color;
             return BitmapPatternBuilder.build(
                 [[0,0,0,1,0,0,0,1,0,0,0],
                  [0,1,0,0,1,0,1,0,0,1,0],
                  [0,0,0,1,0,0,0,1,0,0,0],
                  [1,0,1,0,1,0,1,0,1,0,1],
                  [0,0,0,1,1,1,1,1,0,0,0],
                  [0,1,0,0,1,0,1,0,0,1,0],
                  [0,0,0,1,0,0,0,1,0,0,0],
                  [1,0,1,0,1,0,1,0,1,0,1]],
                 [0x00000000,highLignt])
        }        
    }
}
 import flash.display.Bitmap;
 import flash.display.BitmapData;
 import flash.display.Graphics;
     
 class BitmapPatternBuilder{
     /**
      * creates BitmapData filled with dot pattern.
      * First parameter is 2d array that contains color index for each pixels;
      * Second parameter contains color reference table.
      *
      * @parameter pattern:Array 2d array that contains color index for each pixel.
      * @parameter colors:Array 1d array that contains color table.
      * @returns BitmapData
      */
     public static function build(pattern:Array, colors:Array):BitmapData{
         var bitmapW:int = pattern[0].length;
         var bitmapH:int = pattern.length;
         var bmd:BitmapData = new BitmapData(bitmapW,bitmapH,true,0x000000);
         for(var yy:int=0; yy<bitmapH; yy++){
             for(var xx:int=0; xx<bitmapW; xx++){
                 var color:int = colors[pattern[yy][xx]];
                 bmd.setPixel32(xx, yy, color);
             }
         }
         return bmd;
     }
     
     /**
      * short cut function for Graphics.beginBitmapFill with pattern.
      */
     public static function beginBitmapFill(pattern:Array, colors:Array, graphics:Graphics):void{
         var bmd:BitmapData = build(pattern, colors);
         graphics.beginBitmapFill(bmd);
         bmd.dispose();        
     }
 }