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

forked from: Ghost4Koin

- framerate is caped to 60, no need to put 999999999 fps
- typecasting on every wildcard
- bitshift for better perfs
- resuse of object like point and rect
- Constant value ( StageScaleMode.NO_SCALE instead of "noscale", Keyboard.UP instead of 38 etc.)
- removed unnecessary final
- mouseEnabled = false and mouseChildren = false on displayObject that don't need mouse
- myTextField.selectable = false; accessibility stuff is not needed for games UI like score etc.
- prerender of all tiles instead of building every tiles pixel per pixel on each frame.
Now we cannot colorize or shift tiles at run time but performance is better.
Get Adobe Flash player
by YoupSolo 15 Nov 2014
/**
 * Copyright YoupSolo ( http://wonderfl.net/user/YoupSolo )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/oHss
 */

package
{
    import flash.display.StageQuality;
    import flash.display.StageAlign;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.SampleDataEvent;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.media.*;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
    import flash.ui.Keyboard;

    [SWF(backgroundColor="0xffffff",frameRate="60")]    
    public class Main extends Sprite
    {
        private var b:Bitmap;
        public var frame:uint;
        public var run:Boolean;
        public var score:int;
        
        public var part:Array = [];
        
        public var t:int;
        
        // cameraX, cameraY
        public var camX:Number = 0;
        public var camY:Number = 0;
        
        // mapX, mapY
        public var mx:int;
        public var my:int;
        
        // keyDown
        public var ku:Boolean;
        public var kl:Boolean;
        public var kr:Boolean;
        
        // Player variables
        public var plX:Number = 8 * 16;
        public var plY:Number = 2 * 16;
        public var spdX:Number = 0;
        public var spdY:Number = 0;
        public var pow:Number;
        public var dir:int = 1;
        
        public var txt:TextField;
        
        public var map:BitmapData;                
        public var s:Sprite;
        public var bd:BitmapData;
        
        public const RECT:Rectangle = new Rectangle(0, 0, 160, 100);
        public const CAM_MAXX:int = RECT.width * 16; // 2560
        public const CAM_MAXY:int = RECT.height * 16; // 1600
        public const OFFSETX:int = 6 * 16;
        public const OFFSETY:int = 6 * 16;
        public const SCREENW:int = 16;
        public const SCREENH:int = 12;
        
        
        // done one for all
        public const tilesStr:Array = ("0000000055555555aaaaaaaaffffffffffffffffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9aa19aa14a604a60051005100004000410051005,ff700000f3055555f49aaaaa39ffffff3dffffff1efaaaaa0eaaaaaa0aaaaaaa0aaaaaaa0aaaaaaa0aaaaaaa06aa9aa106824a6001010510040000043c101005,064506458515851585108510851a851a15851585158515855065506550655065064506458515851585108510851a851a15851585158515855065506550655065,f100004f1455551449aaaa614effffb14ffffff14fbaaef14baaaae14aaaaaa14aaaaaa14aaaaaa14aaaaaa146aaaa91468aa29141055041040000103c10043c,5500045551eff24558ffff255cffff355cffffb41fff33b41fff33f41fff33f41ffffff41efff3f41ecf38f410effff41efffff41fffeff41ef28ff450041005,55500455550ef24551efff2551ffff3558ffffc45cffffc45cfcffc45cf3fff45cf3fff458f8ff34580ef3845cfffff41efffff48fffeff4cfb0efb400050005,5555555555100455518ff25558ffff451effff451fffb335cfff3334cfffb332cfefff338fcff3331ecf383210ffff2551fffb4551fff35551eff25555000455,55100555518fb05558fffb4510ffff048fffcc23cfffcc33cfffcc338fffff321efffc345cff0e355cffffb45cfffff41efffff48fffeff4cfb0efb400050005,555555555555555555500555551aa455558ff25551effb4551e3eb4551e3eb4551e3eb4551e3cb4551effb45558ff255551aa455555005555555555555555555,555555555555555555100555550aa455550ff455518ff2555183e2555183e2555183e2555183c255518ff255550ff455550aa455551005555555555555555555,5555555555555555555005555510a4555510f4555508f255550882555508825555088255550802555508f2555510f4555510a455555005555555555555555555,45100451118ae34450f00b051c00002413055084834551c38044110380441102c0055002c0000002820550c3120410c41c00002450f00a05118af34445100451,208151520002818006a2818002020080060200800802818020028181598589895528189859081818520818069028108528181006200028285528182855281818,08908000602069066028590660a069066062890660a0890608206906a69a5526555555559a656994108180a0060280800602800006028020060280a010898162").split(",");
        public const tiles:Array = [];
        public var point:Point = new Point();
        
        // Sounds
        public var snd:Sound;
        public var sndType:int;
        
        public function Main()
        {
            // config stage
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality = StageQuality.LOW;
            stage.stageFocusRect = false;
            stage.tabChildren = false;            

            // add custom menu
            new CustomMenu(this);             
            
            // remove click
            this.mouseEnabled = false;
            this.mouseChildren = false;            
            
            run = false;
            
            // build the Atlas
            for (var i:int = 0 ; i < tilesStr.length; i++ )
            {
                tiles[i] = buildTile( i, false );
            }
            for (i = 0 ; i < tilesStr.length; i++ )
            {
                tiles[i+tilesStr.length] = buildTile( i, true );
            }
            
            map = new BitmapData(RECT.width, RECT.height, false, 0x999999);
            bd = new BitmapData( (SCREENW-1) * 16, (SCREENH-1) * 16 , true, 0xff00cc00); // 240*3 = 720 /  176*3 = 528
            
            // the display
            b = new Bitmap(bd);
            b.scaleX = b.scaleY = 2;
            addChild(b);
            
            // minimap
            b = new Bitmap(map);
            b.alpha = 2 / 3;
            b.x = stage.stageWidth - b.width - 10;
            b.y = 10;
            addChild(b);            
            
            // location square for minimap
            s = new Sprite();
            s.mouseEnabled = false;
            s.graphics.lineStyle(1);
            s.graphics.drawRect(0, 0, 14, 7); // 15 & 11
            addChild(s);
            
            // score
            txt = new TextField();
            txt.defaultTextFormat = new TextFormat("Arial", 24, null, true, null,null,null,null, TextFormatAlign.CENTER );
            txt.width = 300;
            txt.height = 150;            
            txt.selectable = txt.mouseEnabled = false;
            addChild(txt);
            
            SoundMixer.soundTransform = new SoundTransform(.01);
            // the sound object
            snd = new Sound();
            snd.addEventListener(SampleDataEvent.SAMPLE_DATA, gds);            
            
            // action listener
            addEventListener(Event.ENTER_FRAME, ef);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, key);
            stage.addEventListener(KeyboardEvent.KEY_UP, key);    
        }
        
        public function start():void
        {
            var i:int, j:int, k:int, l:int, m:int;
            
            txt.x = -50;
            txt.y = 10;
            frame = 0;
            camX = 0;
            camY = 0;
            plX = 48;
            plY = 64;
            pow = 60;
            spdX = 0;
            spdY = 0;
            dir = 1;
            score = 0;
            part = [];
            
            map.fillRect(RECT, 0x999999);
            
            // Build level
            for (i = 0; i < 400; i++)
            { // Number of platforms
                j = (Math.random() * map.width) >> 0; // x
                k = ((Math.random() * 95) >> 0) + 5; // y (start at 5 as lowest)
                l = (Math.random() * 12) >> 0; // platform length
                
                if (i == 0) // build start platform
                {
                    j = 2;
                    k = 5;
                    l = 5;
                }
                
                for (m = 0; m < l; m++)
                {
                    map.setPixel(j + m, k, 0);
                    if (Math.random() < 0.6)
                        map.setPixel(j + m, k + 1, 0);
                }
                j = int(Math.random() * 160); // x
                k = int(Math.random() * 100); // y
                if (i % 3 == 0 && map.getPixel(j, k) == 0x999999) // dont place gold on top of solid ground
                    map.setPixel(j, k, 0xffff00); // Draw coin
            }
            run = true;
            
            sndType = 1;
            snd.play();
        }
        
        public function key(e:KeyboardEvent):void
        {
            if (e.keyCode == Keyboard.UP)
            {
                ku = (e.type == KeyboardEvent.KEY_DOWN);
            }
            
            if (e.keyCode == Keyboard.LEFT)
            {
                kl = (e.type == KeyboardEvent.KEY_DOWN);
            }
            if (e.keyCode == Keyboard.RIGHT)
            {
                kr = (e.type == KeyboardEvent.KEY_DOWN);
            }
            
            if (e.keyCode == Keyboard.ENTER)
            {
                if (!run)
                    start();
            }
        }
        
        // game loop
        public function ef(e:Event):void
        {
            var i:int, j:int, k:int, l:int, m:int, p0:int, p1:int, p2:int, p3:int, t:int, colA:int;
            
            frame++;
            
            var dmg:int = 0; // check if hit by mine
            
            if (ku)
            {
                spdY -= 1.2;
            }
            
            if (pow <= 0 && run)
            {
                run = false;
                sndType = 4;
                snd.play();
            }
            
            if (kl)
                spdX -= 1.2;
            if (kr)
                spdX += 1.2;
            
            if (spdX < -9)
                spdX = -9;
            if (spdX > 9)
                spdX = 9;
            if (spdY < -9)
                spdY = -9;
            if (spdY > 9)
                spdY = 9;
            
            if (!ku)
                spdY += 1;
            if (!kl && !kr)
                spdX *= 0.5;
            
            if (Math.abs(spdY) < 0.5)
                spdY = 0;
            if (Math.abs(spdX) < 1)
                spdX = 0;
            
            if (!run)
            {
                spdX = 0;
                spdY = 0;
            }
            
            // Update player position and perform collision detection
            if (spdX > 0)
                dir = 1;
            else if (spdX < 0)
                dir = -1;
            
            plX += spdX;
            plY += spdY;
            
            // i = x front, j = x back, k = push back
            i = (dir == 1) ? 15 : 0;
            j = (dir == 1) ? 3 : 12;
            k = (dir == 1) ? -15 : 15;
            
            // Check if collision with coin
            p0 = (plX + 8) >> 4;
            p1 = (plY + 8) >> 4;
            if (map.getPixel(p0, p1) == 0xffff00)
            {
                // Found a coin
                sndType = 3;
                snd.play();
                map.setPixel(p0, p1, 0x999999);
                //pow += 15;
                score++;
                for (l = 0; l < 10; l++)
                {
                    part.push({x: p0 * 16, y: p1 * 16, sx: Math.random() * 30 - 15, sy: Math.random() * 10 - 5, col: 0xbab800, cnt: 8});
                }
                
            }
            
            if (map.getPixel(p0, p1) == 0xff0000)
            {
                map.setPixel(p0, p1, 0x999999);
                pow -= 15;
                dmg = 1;
                // Explosion
                for (l = 0; l < 30; l++)
                {
                    part.push({x: p0 << 4, y: p1 << 4, sx: Math.random() * 30 - 15, sy: Math.random() * 30 - 15, col: 0, cnt: 16});
                }
                
                sndType = 4;
                snd.play();
            }
            
            // Check every corner of the sprite, if 0 then we are inside something solid
            p0 = map.getPixel( int( (plX+i) >> 4 ), int( plY >> 4 ) );        // front head
            p1 = map.getPixel( int( (plX+i) >> 4 ), int( (plY+15) >> 4 ) );    // front foot
            p2 = map.getPixel( int( (plX+j) >> 4 ), int( plY >> 4 ) );        // back head
            p3 = map.getPixel( int( (plX + j) >> 4 ), int( (plY + 15) >> 4 ) );    // back foot
            
            if ( spdY < 0 )
            {
                // Jumping, check head
                if ( p2 == 0 )
                {
                    plY = (int( plY >> 4 ) << 4) + 16;
                    spdY = 0;
                }
                
                if ( p1 == 0 )
                {
                    plX = (int( (plX+i) >> 4 ) << 4) + k// move back
                    spdX = 0;
                }
                
                if ( p0 == 0 && ( p2 != 0 && p1 != 0 ) )
                {
                    // ouch, down or back?!?
                    if ( spdY >= 0 || ((plY) % 16) < 11 )
                    {
                        plX = (int( ( plX ) >> 4 ) << 4) + j// move back
                        spdX = 0;
                    }
                    else
                    {
                        plY = (int( (plY + 15) >> 4 )) << 4;// move down
                        spdY = 0;
                    }
                }
                
                // Jumping / pooping :)
                if ( spdY < -3 )
                {
                    part.push( { x:plX + Math.random() * 12 + 4 , y:plY + 15, sx:Math.random() * 4 - 2 + spdX * 0.5, sy:Math.random() * 4 + 1, col:0x6316128, cnt:4 } );
                }
            }
            else
            {
                if ( p0 == 0 )
                {
                    plX = (int( (plX+i) >> 4 ) << 4) + k// move back
                    spdX = 0;
                }
                
                if ( p3 == 0 )
                {
                    plY = (int( (plY + 15) >> 4 ) << 4) - 16// move up
                    spdY = 0;
                }
                
                if ( p1 == 0 && ( p0 != 0 && p3 != 0) )
                {
                    // ouch, up or back?!?
                    if ( spdY == 0 || ((plY + 15) % 16) > 8 )
                    {
                        plX = (int( ( plX ) >> 4 ) << 4) + j// move back
                        spdX = 0;
                    }
                    else
                    {
                        plY = (int( (plY + 15) >> 4 ) << 4) - 16// move up
                        spdY = 0;
                    }
                }
            }
            
            // Update camera pos from player pos - with smoothing
            camX = camX + (((plX - OFFSETX) - camX) * 0.3);
            camY = camY + (((plY - OFFSETY) - camY) * 0.3);
            
            
            // 2560
            if (camX < 0)
                camX = 0;
            if (camX > CAM_MAXX)
                camX = CAM_MAXX;
            if (camY < 0)
                camY = 0;
            if (camY > CAM_MAXY)
                camY = CAM_MAXY;
            
            // Update map position
            mx = camX >> 4;
            my = camY >> 4;
            
            // Position the rectangle in the mini-map
            s.x = b.x + mx;
            s.y = 10 + my;
            
            txt.text = "ENERGY: " + int(pow) + "\nSCORE: " + score;
            
            // Render bitmap
            bd.lock();
            var rect:Rectangle = new Rectangle(0, 0, 240, 176);
            if (run)
                if (!dmg)
                    bd.fillRect(rect, 0xffffffff);
                else
                    bd.fillRect(rect, 0xffff0000);
            else
            {
                
                bd.fillRect(rect, 0xffffffff);
                txt.x = 10;
                txt.y = 10;
                frame--;
                txt.text = "  FINAL SCORE " + score + "\n\nPRESS ENTER TO START";
                if (frame == 0)
                    txt.text = "PRESS ENTER TO START";
                
            }
            var bol:Boolean = false;
            
            for (i = 0 ; i < SCREENH ; i++)
            {
                for (j = 0 ; j < SCREENW ; j++)
                {
                    p0 = map.getPixel(mx + j, my + i);                    
                    bol = false;
                    if (p0 != 0x999999)
                    {
                        if (run)
                            colA = 0;
                        else
                            colA = 4;
                        p1 = map.getPixel(mx + j, my + i - 1);
                        if (p0 == 0xffff00) // found a gold coin
                        {
                            var coin:Array = [8, 9, 10, 10, 9];
                            t = coin[ (frame >> 2) % 4];
                            bol = ( (frame >> 2) % 4) > 2;
                            colA = 8;
                        }
                        else if (p0 == 0xff0000) // found a mine
                        {
                            t = 11;
                            colA = (frame % 2 == 0) ? 12 : 16;
                        }
                        else if (p1 == 0)
                        {
                            t = 2;
                        }
                        else
                        {
                            p2 = map.getPixel(mx + j - 1, my + i);
                            p3 = map.getPixel(mx + j + 1, my + i);
                            if (p2 == 0 && p3 == 0)
                            {
                                t = 0;
                            }
                            else if (p2 != 0 && p3 != 0)
                            {
                                t = 3;
                            }
                            else
                            {
                                if (p2)
                                    t = 1;
                                else
                                {
                                    t = 1;
                                    bol = true;
                                }
                            }
                        }
                        var val:int = bol ? 14 : 0;
                        drawTo(j * 16 - camX % 16, i * 16 - camY % 16, tiles[t + val]);
                    }
                }
            }
            
            // Render particles
            var p:Object;
            for (i = 0; i < part.length; i++)
            {
                p = part[i];
                bd.setPixel(p.x - camX, p.y - camY, p.col);
                p.x += p.sx;
                p.y += p.sy;
                p.sx *= 0.7;
                p.sy *= 0.7;
                if (p.cnt-- == 0)
                    part.splice(i, 1);
            }
            
            // Render player (frame depending on speed)
            if (spdY == 0 && spdX == 0)
            {
                t = 4;
            }
            else
            {
                if (spdY < 0)
                    t = 7;
                else if (spdY > 0)
                {
                    t = 6;
                }
                else
                {
                    t = (frame >> 2) % 4 + 5;
                    if (t == 8)
                        t = 6;
                }
            }
            
            val = (dir < 0) ? 14 : 0;
            drawTo(int(plX - camX), int(plY - camY), tiles[t+val]);
            
            // Spawn objects, coins or mines
            if (run)
            {
                if (frame % 100 == 0)
                {
                    j = int(Math.random() * 160); // x
                    k = int(Math.random() * 100); // y
                    if (map.getPixel(j, k) == 0x999999) // dont place gold on top of solid ground
                        map.setPixel(j, k, 0xffff00); // Draw coin
                }
                
                if (frame > 450 && frame % 6 == 0)
                {
                    j = int(Math.random() * 160); // x
                    k = int(Math.random() * 100); // y
                    map.setPixel(j, k, 0xff0000); // Mines go everywhere - even inside solid ground
                }
            }
            else
            {
                // game title
                drawTo(100, 52, tiles[12]);
                drawTo(116, 52, tiles[13]);
            }
            
            bd.unlock();        
        }
        
        [Inline]
        final public function drawTo(x:int, y:int, bmd:BitmapData):void
        {
            point.x = x;
            point.y = y;
            bd.copyPixels( bmd, bmd.rect, point,null,null,true);
        }
        
        public function buildTile(idx:int, inv:Boolean):BitmapData
        {
            var bd:BitmapData = new BitmapData(16, 16, true, 0x0);            
            var n:int, o:int, q:int, col:int, px:int, py:int;
            var ca:int;
            var str:String = tilesStr[idx];
            
            
            if (idx == 0 || idx == 1 || idx == 2 || idx == 3) {
                // frame tuile / gris
                ca = 0;                
            }else if (idx == 4 || idx == 5 || idx == 6 || idx == 7) {
                // frames perso / noir
                ca = 20;                
            }else if (idx == 8 || idx == 9 || idx == 10) {
                //    frames pieces / jaune
                ca = 8;
            }else if(idx == 11){                
                // frames bombes / rouge
                ca = 16;
            }else {
                ca = 20;
            }
            
            var colors:Array = [0xff000000, 0xff606060, 0xffb0b0b0, 0xffffffff, 0xff000000, 0xffFEB0B1, 0xffcc0000, 0, 0xff3e4000, 0, 0xffaba000, 0xfffff568, 0xff000000, 0, 0xff000000, 0xffff0000, 0xff000000, 0, 0xffff0000, 0xff000000, 0xff000000, 0, 0xffb0b0b0, 0xffffffff];
            
            for (n = 0; n < 128; n++)
            {
                for (o = 0; o < 2; o++)
                {
                    q = (n * 2 + o);
                    col = colors[ca + (uint("0x" + str.charAt(n)) >> (o * 2) & 0x3)];
                    if (col != 0)
                    {
                        if (!inv)
                        {
                            px = q % 16;
                        }
                        else
                        {
                            px = 15 - (q % 16);
                        }
                        bd.setPixel32(px, (q >> 4), col);
                    }
                }
            }
            
            return bd;
        }        
        
        public function gds(e:SampleDataEvent):void
        { 
            //generate dynamic sound
            // where, in time, the sound begins and ends, this affects the where on the sine curve the sound will start playing.            
            var i:int;
            var beginAt:int = 100;
            var endAt:int = 5000;
            var hz:Number = 44.1;
            var r:Number = (e.position / hz) + beginAt;
            var pitch:int = 1000;
            var flt:Number = .0;
            var L:int = 8001;
            var f:Number;
            
            for (i = 0; i < 4096; i++)
            {
                if (sndType == 1)
                {
                    beginAt = 100;
                    endAt = 2000
                    pitch = 1000
                    r = (e.position / hz) + beginAt;
                    
                    if (r < endAt)
                    {
                        f = (e.position / hz) + L / 2; //time elapsed + 300 to offset the sound
                        flt = Math.sin((Number(i) / Math.PI / (1 - (r / pitch)) / 15)) * 40000;
                    }
                }
                if (sndType == 3)
                {
                    beginAt = 850;
                    endAt = 920;
                    hz = 44.1;
                    L = 1000;
                    pitch = 1000
                    r = (e.position / hz) + beginAt;
                    
                    if (r < endAt)
                    {
                        f = (e.position / hz) + L / 2; //time elapsed + 300 to offset the sound
                        flt = Math.tan(Number(i) / Math.PI / (1 - (r / pitch)) / 80) * 40000;
                    }
                }
                if (sndType == 4)
                {                    
                    beginAt = 500;
                    endAt = 920;
                    hz = 44.1;
                    L = 1000;
                    pitch = 1000;
                    r = (e.position / hz) + beginAt;
                    
                    if (r < endAt)
                    {
                        f = (e.position / hz) + L / 2; //time elapsed + 300 to offset the sound
                        flt = Math.tan(Number(i) / Math.PI / (0 - (r / pitch)) / 80) * 40000;
                    }
                }
                
                if (r <= endAt)
                {
                    e.data.writeFloat(flt);
                }
                
            }
        }
    }

}

import flash.display.Sprite;
import flash.events.ContextMenuEvent;
import flash.net.navigateToURL;
import flash.net.URLRequest;
import flash.ui.ContextMenu;
import flash.ui.ContextMenuItem;


internal class CustomMenu
{   
    private const NAME:String = "4K0ins";
    public function CustomMenu(ref:Sprite):void
    {
        var appContextMenu:ContextMenu = new ContextMenu;
        appContextMenu.hideBuiltInItems();
        var cmi:ContextMenuItem = new ContextMenuItem(NAME);
        var credits:ContextMenuItem = new ContextMenuItem("by YopSolo");
        appContextMenu.customItems.push(cmi);
        appContextMenu.customItems.push(credits);

        cmi.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, _onClickCollection);
        credits.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, _onClickCredits);

        ref.contextMenu = appContextMenu;
    }    

    private function _onClickCollection(e:ContextMenuEvent):void
    {
        navigateToURL(new URLRequest('http://www.yopsolo.fr/wp/2014/10/30/4k-plateformer/'), '_blank');
    }

    private function _onClickCredits(e:ContextMenuEvent):void
    {
        navigateToURL(new URLRequest('http://www.yopsolo.fr'), '_blank');
    }
}