forked from: forked from: Ghost4Koin

by s8t1h12akj forked from forked from: Ghost4Koin (diff: 2)
♥0 | Line 584 | Modified 2014-11-20 09:38:53 | MIT License
play

ActionScript3 source code

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

// forked from YoupSolo's forked from: Ghost4Koin
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スタートはEnterキーを押します\n";
                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');
    }
}