forked from: forked from: keyboard Test

by raa forked from forked from: keyboard Test (diff: 1)
arrows or [wad] to move,rotation
--------------------------------------------------------------------------------

KeyMapper Test
비행기의 손맛을 느껴보자!
@author jidolstar
@see http://blog.jidolstar.com/672
♥0 | Line 277 | Modified 2016-01-10 10:32:13 | MIT License
play

ActionScript3 source code

/**
 * Copyright raa ( http://wonderfl.net/user/raa )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/8kRr
 */

// forked from ririz's forked from: keyboard Test 
// forked from jidolstar's keyboard Test 
// arrows or [wad] to move,rotation
//--------------------------------------------------------------------------------
package {
    import com.bit101.components.Label;
    import com.bit101.components.Style;

    import flash.display.*;
    import flash.events.*;
    import flash.filters.BlurFilter;
    import flash.filters.DropShadowFilter;
    import flash.geom.*;
    import flash.text.TextField;

    import mx.states.State;

    import net.hires.debug.Stats;

    [SWF(backgroundColor='#000000', frameRate='30')]

    /**
     * KeyMapper Test
     * 비행기의 손맛을 느껴보자!
     * @author jidolstar
     * @see http://blog.jidolstar.com/672
     */
    public class game_key_mapper extends Sprite {

        function game_key_mapper() {
            if (stage) {
                ADDED_TO_STAGE();
            } else {
                addEventListener(Event.ADDED_TO_STAGE, ADDED_TO_STAGE);
            }
        }

        private function ADDED_TO_STAGE($e:Event=null):void {
            // stage
            stage.tabChildren=false;
            stage.stageFocusRect=false;
            stage.mouseChildren=false;
            stage.frameRate=30;
            stage.align=StageAlign.TOP_LEFT;
            //stage.scaleMode = StageScaleMode.NO_SCALE;

            // keyboard mapper
            _key=new KeyMapper(stage);
            _key.map(0, 37, 65).map(1, 38, 87).map(2, 39, 68); //Left, Up, Right

            // background
            addChild(_landscape);

            // rendering layer 
            addChild(new Bitmap(_screen));
            
            tfDebug = new TextField();
            tfDebug.x = 300;
            
            // initialize
            _plane=new Plane(_screen.width >> 1, _screen.height >> 1, 0);

            // event listener
            stage.addEventListener(Event.ENTER_FRAME, ENTER_FRAME);

            // Stats
            addChild(new Stats);

            // key control help
            Style.LABEL_TEXT=0xffffff;
            new Label(this, 75, 0, "'right rotation' : right or D").filters=[new DropShadowFilter(2.0, 45)];
            new Label(this, 75, 15, "'left rotation' : left or A").filters=[new DropShadowFilter(2.0, 45)];
            new Label(this, 75, 30, "'acceleration'  : up or W").filters=[new DropShadowFilter(2.0, 45)];
            addChild( tfDebug);
            tfDebug.textColor = 0xffffff;
            tfDebug.text = "11111111111111111111";
        }
        private var tfDebug:TextField;
        private function ENTER_FRAME($e:Event):void {
            //update
            _plane.update();
            tfDebug.text = String(_key.flag);
            //rendering
            _screen.lock();
            //_screen.colorTransform(_screen.rect,new ColorTransform(1,1,1,0.9,0,0,0));
            _screen.fillRect(_screen.rect, 0x000000);
            _plane.render();
            _screen.unlock();
        }
    }
}
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.*;
import flash.system.*;
import flash.utils.*;

import mx.utils.*;

const WIDTH:Number=465, HEIGHT:Number=465;

var _key:KeyMapper;
var _plane:Plane;
var _landscape:Landscape=new Landscape(WIDTH, HEIGHT);
var _screen:BitmapData=new BitmapData(WIDTH, HEIGHT, true, 0x0);

// Key mapper
//----------------------------------------------------------------------------------------------------
class KeyMapper {
    public var flag:int=0;
    private var _mask:Vector.<int>=new Vector.<int>(256, true);

    function KeyMapper(stage:Stage):void {
        stage.addEventListener("keyDown", function(e:KeyboardEvent):void { flag|=_mask[e.keyCode]; });
        stage.addEventListener("keyUp", function(e:KeyboardEvent):void { flag&=~(_mask[e.keyCode]);    });
    }

    public function map(bit:int, ... args):KeyMapper {
        for (var i:int=0; i < args.length; i++) {
            _mask[args[i]]=1 << bit;
        }
        return this;
    }
}

// Resource
//----------------------------------------------------------------------------------------------------
class DisplayImage {
    public var bmp:BitmapData;
    public var rect:Rectangle;
    public var cx:int, cy:int;

    function DisplayImage($bmp:BitmapData, $cx:int, $cy:int) {
        bmp=$bmp;
        cx=$cx;
        cy=$cy;
        trimming();
    }

    private function trimming():void {
        var r:Rectangle=bmp.getColorBoundsRect(0xFF000000, 0x00000000);
        var temp:BitmapData=new BitmapData(r.width, r.height, true, 0x00000000);
        cx-=r.x;
        cy-=r.y;
        temp.copyPixels(bmp, r, new Point(0, 0));
        bmp.dispose();
        bmp=temp;
        rect=r;
    }
}

// Plane
//----------------------------------------------------------------------------------------------------
class Plane {
    private const D2R:Number=Math.PI / 180; //Degree -> Radian
    private const ROT_STEPS:Number=100;
    private const ROT_STEP_DIRECTION:Number=ROT_STEPS / 360;
    private const FRAMES:int=3;
    private var loader:Loader=new Loader();
    private var rotArr:Vector.<DisplayImage>=new Vector.<DisplayImage>(3 * ROT_STEPS, true);
    private var r:Number=0; //rotation
    private var vr:Number=0; //rotation velocity
    private var ar:Number=0; //rotation acceleration
    private var x:Number=0; //x-axis position
    private var y:Number=0; //y-axis position
    private var vx:Number=0; //x-axis velocity
    private var vy:Number=0; //y-axis velocity
    private var ax:Number=0; //x-axis acceleration
    private var ay:Number=0; //y-axis acceleration
    private var currentImg:DisplayImage;
    private var currentFrame:int=0;
    private var frameInterval:Number=0;
    private var ready:int=0;

    function Plane($x:Number, $y:Number, $rotation:Number) {
        // 원본이미지를 Base64로 Encode 하는 방법 
        //[Embed(source="../assets/brownplane.png")]
        //private var PLANE:Class;
        //var plane:Bitmap = new PLANE as Bitmap;
        //var encoder:Base64Encoder = new Base64Encoder;
        //var byte:ByteArray = (new PNGEncoder).encode(plane.bitmapData);
        //encoder.encodeBytes( byte );
        //trace( encoder.drain() );

        // plane base64 data 
        // http://www.brighthub.com/internet/web-development/articles/11010.aspx
        // plane image : http://www.brighthub.com/internet/web-development/articles/11010.aspx
        var pdata:String="", byteArr:ByteArray, base64Dec:Base64Decoder=new Base64Decoder();
        pdata+="iVBORw0KGgoAAAANSUhEUgAAAMMAAABBCAYAAABsBxB5AAAF5UlEQVR42u2dr1fcWBiGx1UgViAq";
        pdata+="KhCIFRUViAoEAoGsQFZUjFgxYkUFArECMaJ/AKKiogKBWIkYUYlArEAgVyAqkZVZ3tt9c765JJmE";
        pdata+="mUBO53nP+U6SmztfvvuU5N7cH+lohBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIoV9Pm3uTYmdnpzQd";
        pdata+="wwAGa8fgxet3xV8Hr4q/j3eLq8+HaatjpcMABuvEYLS//aKYfToobmeT4u7qKG11rHQYwGBtGKga";
        pdata+="1N2vJ4EA/Li9TlsdK30dqkkY/MIMilwbvyU7OjqaM+Xd2HlffJ3sFDfnH4ri32mCoK2Ola7zXX0O";
        pdata+="QXlcjjdXFwZdfA6ZwTJ/B118Dkq/b45SQXR3y7SvtLydqHRViRGCjpWetxfb+IQBDAZX7TlYFUjm";
        pdata+="oGOVt7W1NQfBZgg639UnDGAwLG3vpd4ABRrvcqXpXA5BhRm9PSjNhYsQ2vqEAQyeRC8PjtPdJ1M7";
        pdata+="TtWXTMHaVF19Otwu79wYsNL+eLuZ8si0r8Kq4F9ubovrH0Xa6ljped46n64mYxyOTXE6ZsUPAxg8";
        pdata+="moHbc+rmchutyZQvVmN5wAbkfeV99/l87iVQx0rP8zZB6Bpfl/5rGMCgBBAvbnO7Lj9Wl9giCG7r";
        pdata+="GcL4fJaeBjYdG0LM2wRB15XFNmeMzefjb9qAgAEM0ouKLuw77e7mWxmQ7PvleUrTNqbLNJReF7DO";
        pdata+="VUG4+H5XWhWEtj7bxOcng/w3vXTBAAbl0yBCiHZzMS2urq6K6eV12qbjcP7k5KQMOL8TfS6vHj9e";
        pdata+="XJZWVT229dkmvgih6akAAxjMzRVxOyzaP1+PU7Cj0be01XE8v+juzSFsTY5TwW06ziEs8tklPrcX";
        pdata+="F819gQEMyupRb+4OVKbuK9l0Oi3Ozs7SBWazWXF5OnlwAQcc+4xdcOezb+2r4Db7yPPW+cz/oVI8";
        pdata+="93EpPsWpeB27yyJ/Kt+iJgIMYFA+Fd6/2Sg+7r2cgyHTsPfp6encBeKF6qqyKgiurmwuWB2Eqpeg";
        pdata+="PAbFpfgUZ4xbflQelavtyyMMYFCC0MxB/ejP3c1UpeRA8iAiBAUjixCcz340B8U9ANp6Tkqet85n";
        pdata+="1fXzgituxa9yqDxduxVhAIOyqtTonn6cA8kvaPMLjRdq+OWmCYJnKzZBqPJZF0Ne8DQd+L4cjxm2";
        pdata+="hwEMHow8aiRPI3u7r0YlEJkuePrhdTJDGI/HZcDar4NQNXW3DkKVT+X1tRWHY1J8HoVU3KsafYUB";
        pdata+="DFoDUTBNEGK1lbcrY5WX522CEAuueJa+82EAg2WAeH6KgtFdnFdl8SkQC6kXI89l1zb2IsS8dT51";
        pdata+="vV7vfBjA4LGKsxAVaGzTqfr6Mn6TzIX0ulebX3503nndLq3yOTercSCCAQxGceWS17R6PaurMRUu";
        pdata+="WgQRAUTT7+p8eiUUDGAwuJtB1ZMDdl+wA/ZU3DglN4KIAyF53jqfg6gOYQCDOqlKU6E8ZK59pVX1";
        pdata+="X0cQBlDV/9vWJwxgMCgdHv5sx3nIXPtKa+q/ttW9/XfxCQMYDA6Cq7JVBNyHTxjAoHft7+8/CFhp";
        pdata+="Q/MJAxj0Li8KiQs4lh386MMnDGDwJD0JecDLvu334RMGMHgS+UsG/hrCUH3CAAa9SwMkDlj7Q/UJ";
        pdata+="Axj0Lg2QeFHGqj7/14dPGMCgl5elNCS+vVd+SEpzSWT5KOIyFn2m+Sj31/NHomAAg2dloItruq5G";
        pdata+="An23ehah9jU66Lko+YLsrtbkU9dUHM8BAwYw+Kn/v3+pQOLCDAXpEUIH7IlY7gmIy/zqtvE7N1U+";
        pdata+="7c8gnuW7ozCAQQ4hD9iDIk0QFtkin/EbOEP4Q4DBGjOIEOJ8dL/xV0GIINpYk8+h/SHAYI0ZNLUV";
        pdata+="qyDknwNp85HY2FbMfQ69vQyD9WGQpKm2CsArkrTvZX9elKGtF2zHvE0W89tP7jPmfc7/HRIGMChV";
        pdata+="tQbW3V/aX0V3Wu5zaGteYQCD2qeEv1awqju1D58wgMGTtSNX3XbrwycMYIAQQgghhBBCCCGEEEII";
        pdata+="IYQQWqH+A2OxL7+zKnbXAAAAAElFTkSuQmCC";
        // decode
        base64Dec.decode(pdata);
        byteArr=base64Dec.toByteArray();

        // load
        loader.loadBytes(byteArr, new LoaderContext(false, ApplicationDomain.currentDomain, null));
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, COMPLETE);

        //initialize
        x=$x;
        y=$y;
        r=$rotation;
    }

    private function COMPLETE($e:Event):void {
        loader=null;
        var i:int, j:int, k:int, src:BitmapData, temp:BitmapData;
        var rect:Rectangle, destPoint:Point, frameWidth:Number, frameHeight:Number, matrix:Matrix;
        var stepBmpList:Vector.<Bitmap>;

        src=Bitmap(LoaderInfo($e.target).content).bitmapData
        destPoint=new Point(0, 0);
        frameWidth=src.width / FRAMES;
        frameHeight=src.height;

        j=FRAMES;
        stepBmpList=new Vector.<Bitmap>(FRAMES, true);
        while (j--) {
            rect=new Rectangle(j * frameWidth, 0, frameWidth, frameHeight);
            temp=new BitmapData(frameWidth, frameHeight, true, 0x0);
            temp.copyPixels(src, rect, destPoint);
            stepBmpList[j]=new Bitmap(temp);
        }

        j=FRAMES;
        matrix=new Matrix;
        rect=new Rectangle(frameWidth, 0, frameWidth, frameHeight);
        while (j--) { //frame 
            i=ROT_STEPS;
            k=j * ROT_STEPS;
            while (i--) { //rotation
                matrix.identity();
                matrix.translate(-frameWidth / 2, -frameHeight / 2);
                matrix.rotate((360 / ROT_STEPS * i) * D2R);
                matrix.translate(frameWidth / 2, frameHeight / 2);
                temp=new BitmapData(frameWidth, frameHeight, true, 0x0);
                temp.draw(stepBmpList[j], matrix, null, null, null, true);
                rotArr[i + k]=new DisplayImage(temp, frameWidth / 2, frameHeight / 2);
            }
        }
        ready=1;
    /*
       var a:Number = 0;
       var b:int = 0;
       for(i=0;i<rotArr.length;i++) {
       var img:DisplayImage = rotArr[i];
       _screen.copyPixels(img.bmp,img.rect,new Point((a-b*10)*img.rect.width,b * img.rect.height));
       a += 1;
       b = a/10 ;
     }*/
    }

    public function update():void {
        if (!ready)
            return;
        var a:Number, inkey:int=_key.flag;
        
        // rotation
        ar=(((inkey & 4) >> 2) - (inkey & 1)) * 0.5;
        vr+=ar;
        r+=vr;
        ar*=.96;
        vr*=.92;
        (r < 0) ? r+=360 : (r > 360) ? r-=360 : 0;

        // move
        a=-((inkey & 2) >> 1) * 1.2;
        ax=a * Math.sin((360 - r) * D2R);
        ay=a * Math.cos((360 - r) * D2R);
        vx+=ax;
        vy+=ay;
        x+=vx;
        y+=vy;
        ax*=.96;
        ay*=.96;
        vx*=.90;
        vy*=.90;

        // check boundary
        (x > WIDTH) ? x=0 : (x < 0) ? x=WIDTH : 0;
        (y > HEIGHT) ? y=0 : (y < 0) ? y=HEIGHT : 0;

        // find image
        currentImg=rotArr[int(r * ROT_STEP_DIRECTION) + ROT_STEPS * currentFrame];

        // check frame
        if (frameInterval + 100 < getTimer()) {
            if (++currentFrame === FRAMES) {
                currentFrame=0;
            }
            frameInterval=getTimer();
        }
    }

    public function render():void {
        if (!ready)
            return;
        _screen.copyPixels(currentImg.bmp, currentImg.rect, new Point(x - currentImg.cx, y - currentImg.cy));
    }
}

// Background
//----------------------------------------------------------------------------------------------------
class Landscape extends Bitmap {
    // This color gradation is refered from psyrak's BumpyPlanet
    // http://wonderfl.net/code/d79cd85845773958620f42cb3e6cb363c2020c73
    public var gradation:*={color: [0x000080, 0x0066ff, 0xcc9933, 0x00cc00, 0x996600, 0xffffff], alpha: [100, 100, 100, 100, 100, 100], ratio: [0, 96, 96, 128, 168, 192]};
    public var pixels:BitmapData, texture:BitmapData, rect:Rectangle;
    private var pt:Point=new Point();

    function Landscape(w:int, h:int) {
        texture=new BitmapData(w * 2, h * 2, false, 0);
        pixels=new BitmapData(w, h, false, 0);
        rect=new Rectangle(0, 0, w, h);
        super(pixels);

        // height map
        var hmap:BitmapData=new BitmapData(w, h, false, 0);
        hmap.perlinNoise(w * 0.5, h * 0.5, 10, Math.random() * 0xffffffff, true, false, 0, true);
        hmap.colorTransform(hmap.rect, new ColorTransform(1.5, 1.5, 1.5, 1, -64, -64, -64, 0));

        // texture
        var mapR:Array=new Array(256), mapG:Array=new Array(256), mapB:Array=new Array(256);
        var gmap:BitmapData=new BitmapData(256, 1, false, 0), render:Shape=new Shape(), mat:Matrix=new Matrix();
        mat.createGradientBox(256, 1, 0, 0, 0);
        render.graphics.clear();
        render.graphics.beginGradientFill("linear", gradation.color, gradation.alpha, gradation.ratio, mat);
        render.graphics.drawRect(0, 0, 256, 1);
        render.graphics.endFill();
        gmap.draw(render);
        for (var i:int=0; i < 256; i++) {
            var col:uint=gmap.getPixel(i, 0);
            mapR[i]=col & 0xff0000;
            mapG[i]=col & 0x00ff00;
            mapB[i]=col & 0x0000ff;
        }
        gmap.dispose();
        mat.identity();
        texture.paletteMap(hmap, hmap.rect, hmap.rect.topLeft, mapR, mapG, mapB);

        // shading
        var smap:BitmapData=new BitmapData(w, h, false, 0);
        smap.applyFilter(hmap, hmap.rect, hmap.rect.topLeft, new ConvolutionFilter(3, 3, [-1, -1, 0, -1, 0, 1, 0, 1, 1], 1, 0, true, true));
        texture.draw(smap, null, new ColorTransform(4, 4, 4, 1, 160, 160, 160, 0), "multiply");

        // copy 2x2
        pt.x=w;
        pt.y=h;
        texture.copyPixels(texture, hmap.rect, pt);
        pt.x=0;
        pt.y=h;
        texture.copyPixels(texture, hmap.rect, pt);
        pt.x=w;
        pt.y=0;
        texture.copyPixels(texture, hmap.rect, pt);
        pt.x=0;
        pt.y=0;

        // rendering
        pixels.copyPixels(texture, rect, pt);
    }
}