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: Space iVaders

Attempt to build a Simple Space Invaders in one session 
(3 hours + couple of extra for bug fixes and extras)

Left and Right arrow keys to move.
Space to fire

Used some pixel graphic code from the Professional Fladdict comp.

...
@author Swingpants
/**
 * Copyright Martin.Lilliendal.Hansen ( http://wonderfl.net/user/Martin.Lilliendal.Hansen )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/sXFM
 */

// forked from swingpants's Space iVaders
package 
{
/**********************************************************
Attempt to build a Simple Space Invaders in one session 
(3 hours + couple of extra for bug fixes and extras)

 Left and Right arrow keys to move.
 Space to fire
 
 Used some pixel graphic code from the Professional Fladdict comp.
***********************************************************/
    import flash.display.Sprite;
    import flash.display.MovieClip;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.events.KeyboardEvent
    import flash.geom.Point;
    import flash.text.TextField;
    import flash.ui.Keyboard;
    
    import caurina.transitions.Tweener;
    
    /**
     * ...
     * @author Swingpants
     */
[SWF(width=450, height=450, backgroundColor=0x000000)]   
     public class Main extends Sprite 
    {
        
        private const screenW:int = 450
        private const screenH:int = 450
        
        private var cols:Array = []
        private var rightmost_col:int = 0
        private var leftmost_col:int = 9999
        private var bottom_most:int=0
        
        private var tank:Bitmap
        
        private var saucer:Bitmap
        private var saucer_flying:Boolean = false
        private var saucer_speed:int = 2
    
        private var vader1:BitmapData
        private var vader2:BitmapData
        private var next:BitmapData;
        private var pattern:BitmapData;
        
        private var anim_count:int = 0
        private var anim_speed:int = 21
        private var max_anim_speed:int = 21
        private var min_anim_speed:int = 7
        private var ivader_dir:int = 2
        private var ivader_max_speed:int=7
        private var num_in_row:int = screenW / 30
        private var num_in_col:int = 12
        
        private var tf:TextField = new TextField()
        
        private var y_drop:int=0
        private var tank_speed:int = 2
        private var bullet_speed:int = 4
        private var max_bullets:int = 5
        private var max_bombs:int = 5
        private var bomb_ratio:Number=0.92
        
        private var leftFlag:Boolean = false
        private var rightFlag:Boolean = false
        private var spaceFlag:Boolean = false
        
        private var tank_bullets:Array = []
        private var vader_bombs:Array = []
        
        private var canvas:Sprite = new Sprite()
        
        private var lives_left:int = 3
        private var score:int = 0
        
        private var cease_fire:Boolean = false
        
        private var ivader_count:int = 0
        private var ivaders_down:int = 0
        
        
    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);
            
            stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
            
             //generate bitmap pattern.
            vader1 = fig1();
            vader2 = fig2();

            pattern = vader1.clone();
            next    = vader2;
            
            for (var i:int = 0; i < num_in_row; i++)
                {
                    cols.push(initIVaderCol(50 + i * 20, pattern))
                    if (pattern == vader1) pattern = vader2
                        else pattern=vader1
                }
            
            tank = new Bitmap(tankBmd())
            tank.x = screenW * 0.5
            tank.y = screenH-50
            addChild(tank)
            
            saucer = new Bitmap(saucerBmd())
            saucer.name = "ivader_saucer"
            saucer.x=-999
            saucer.y = 20
            addChild(saucer)
            
            canvas.name="canvas"
            addChild(canvas)
            
            tf.textColor = 0xFFFFFF
            renderScore()
            
            addChild(tf)
            
            initParams()
            
            addEventListener(Event.ENTER_FRAME, update)
        }
        
    private function initParams():void
        {
            ivader_dir = 2
            anim_speed = 21
            tank_speed = 2
            bomb_ratio = 0.92
            lives_left = 3
            max_bombs = 5
            ivaders_down = 0
            bottom_most=0
        }
        
    private function resetVaders():void
        {
            var len:int = cols.length
            for (var i:int = 0; i < len; i++)
                {
                    for (var j:int = 0; j < num_in_col; j++)
                        {
                            cols[i][j].x = 50 + i * 20
                            cols[i][j].y = 50 + 20 * j
                            addChild(cols[i][j])
                        }
                }
            max_bombs++
            bomb_ratio*=.92
        }
        
    private function renderScore():void
        {
            tf.text = "LIVES:"+lives_left+"\nSCORE:"+score
        }
        
        
    private function initIVaderCol(x_val:int, bmd:BitmapData):Array
        {
            var arr:Array=[]
            for (var i:int = 0; i < num_in_col; i++)
                {
                    var bmp:Bitmap = new Bitmap(bmd)
                    bmp.name="ivader"+ivader_count
                    bmp.x=x_val
                    bmp.y = 50+20 * i
                    arr.push(bmp)
                    addChild(bmp)
                    
                    ivader_count++
                }
            return arr
        }
        
    
        
//***************************MAIN LOOP***************************
    private function update(e:Event):void
        {
            anim_count++
            if (anim_count == anim_speed)
                {
                    anim_count = 0
                    var len:int = cols.length
                    leftmost_col = 999
                    rightmost_col = -999
                    for (var i:int = 0; i < len; i++)
                        {
                            if (updateIVaderCol(cols[i]))
                                {
                                    if (leftmost_col > i) leftmost_col = i
                                    if (rightmost_col < i) rightmost_col = i
                                }
                        }
                    if (leftmost_col != 999 && rightmost_col != -999)
                        {
                        if (cols[rightmost_col][0].x > screenW - 30 || cols[leftmost_col][0].x < 30)
                            { 
                                y_drop = 10
                                ivader_dir = -ivader_dir 
                            }
                            else y_drop = 0
                        }
                        else
                        {
                            //ALL IVADERS KILLED
                            trace("ALL IVADERS KILLED")
                            resetVaders()
                        }
                    if (bottom_most > screenH - 60 && !cease_fire)
                        {//Ivaders reached ground
                            lives_left = 0
                            if (tank.parent) tank.parent.removeChild(tank)
                            cease_fire = true
                            Tweener.addTween(this,{time:6,onComplete:restartTank})
                        }
                }
                
            if (saucer_flying) renderSaucer()
                else 
                {
                    if(Math.random()>0.99)launchSaucer()
                }
            if (leftFlag)
                {
                    tank.x -= tank_speed
                    checkBoundaries()
                }
            if (rightFlag)
                {
                    tank.x += tank_speed
                    checkBoundaries()
                }
            if (spaceFlag) fireBullet()
            
            canvas.graphics.clear()
            renderTankBullets()
            renderVaderBombs()
            renderScore()
        }
    
    private function updateIVaderCol(arr:Array):Boolean        
    {
            var last_vader:int = -1

            for (var i:int = 0; i < num_in_col;i++ )
                {
                    arr[i].x += ivader_dir
                    arr[i].y += y_drop
                    if (arr[i].parent)
                        {
                            if (arr[i].bitmapData == vader1) arr[i].bitmapData = vader2
                                else arr[i].bitmapData = vader1
                            last_vader = i
                            if(arr[i].y>bottom_most)bottom_most=arr[i].y
                        }
                }
            if (Math.random() > bomb_ratio && last_vader > -1 && !cease_fire) dropBomb(new Point(arr[last_vader].x + 6, arr[last_vader].y + 10))
            
            return last_vader>-1 //true if column occupied
        }
        
    private function launchSaucer():void
        {
            saucer_flying=true
            if (Math.random() > 0.5)
                {
                    saucer.x = screenW + 50
                    saucer_speed=-Math.abs(saucer_speed)
                }
                else
                {
                    saucer.x = -50
                    saucer_speed=Math.abs(saucer_speed)
                }
            addChild(saucer)
        }
    private function renderSaucer():void
        {
            saucer.x += saucer_speed
            if (saucer.x > screenW + 50 || saucer.x < -50)
                {
                    if(saucer.parent)removeChild(saucer)
                    saucer_flying=false
                }
        }
    private function renderVaderBombs():void
        {
            var len:int = vader_bombs.length
            var remove:Array = []
            var i:int
            canvas.graphics.lineStyle(2, 0xFF0000)
            
            for (i = 0; i < len; i++)
                {
                    vader_bombs[i].y += bullet_speed
                    if (vader_bombs[i].y < screenH)    
                        {
                            if (this.getObjectsUnderPoint(vader_bombs[i])[0]==tank)
                                {
                                    tankHitHandler()
                                    //bulletHitHandler(this.getObjectsUnderPoint(tank_bullets[i])[0])
                                    remove.push(i)
                                }
                            canvas.graphics.drawCircle(vader_bombs[i].x, vader_bombs[i].y, 1)
                        }
                        else remove.push(i)
                }
            //Remove bullets from array 
            if (remove.length > 0)
                {
                    remove.sort(Array.NUMERIC)
                    len = remove.length
                    for (i = len-1; i >= 0; i--)
                        {
                            vader_bombs.splice(remove[i],1)
                        }
                }
        }
    private function tankHitHandler():void
        {
            lives_left--
            tank.parent.removeChild(tank)
            cease_fire = true
            Tweener.addTween(this,{time:4,onComplete:restartTank})
        }
    private function restartTank():void
        {
            if (lives_left == 0)
                {
                    lives_left = 3
                    score = 0
                    
                    resetVaders()
                    initParams()
                }
            cease_fire = false
            tank.x = screenW * 0.5
            addChild(tank)
        }
    private function dropBomb(posn:Point):void
        {
            if(vader_bombs.length<=max_bombs) vader_bombs.push(new Point(posn.x, posn.y))
        }
        
    private function renderTankBullets():void
        {
            var len:int = tank_bullets.length
            var remove:Array = []
            var i:int
            canvas.graphics.lineStyle(2, 0x00FF00)
            
            for (i = 0; i < len; i++)
                {
                    tank_bullets[i].y -= bullet_speed
                    if (tank_bullets[i].y > 0)    
                        {
                            if (this.getObjectsUnderPoint(tank_bullets[i]).length>0)
                                {
                                    if(this.getObjectsUnderPoint(tank_bullets[i])[0].name.substr(0,6)=="ivader" )
                                        {
                                            bulletHitHandler(this.getObjectsUnderPoint(tank_bullets[i])[0])
                                            remove.push(i)
                                        }
                                }
                            canvas.graphics.drawRect(tank_bullets[i].x, tank_bullets[i].y, 1, 3)
                        }
                        else remove.push(i)
                }
            //Remove bullets from array 
            if (remove.length > 0)
                {
                    remove.sort(Array.NUMERIC)
                    len = remove.length
                    for (i = len-1; i >=0; i--)
                        {
                            tank_bullets.splice(remove[i],1)
                        }
                }
        }
        
    private function fireBullet():void
        {
            if(tank_bullets.length<=max_bullets && !cease_fire) tank_bullets.push(new Point(int(tank.x + tank.width * 0.5), tank.y-1))
            spaceFlag=false
        }
    private function bulletHitHandler(b:*):void
        {
            score += 100
            b.parent.removeChild(b)
            ivaders_down++
            var n:int = 2 + Math.floor(ivaders_down / (ivader_count * 0.25))
            ivader_dir = ivader_dir > 0?n: -n
            
            anim_speed=max_anim_speed-ivaders_down/(max_anim_speed-min_anim_speed)
            if (anim_speed<min_anim_speed)anim_speed=min_anim_speed
            trace("ivader_dir="+ivader_dir+"   leftmost="+leftmost_col+"  rightmost="+rightmost_col)
        }
    private function checkBoundaries():void
        {
            if (tank.x < 5) tank.x = 5
            else
            if(tank.x>screenW-tank.width-5)tank.x=screenW-tank.width-5
        }
        
    public function fig1():BitmapData
        {
            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, 0xffCCCCCC]
            );
        }
        
    public function fig2():BitmapData
        {
            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, 0xffCCCCCC]
            );
        }
        
    public function tankBmd():BitmapData
        {
            return BitmapPatternBuilder.build(
                [[0,0,0,0,0,0,0,0,0,0,0],
                 [0,0,0,0,0,0,0,0,0,0,0],
                 [0,0,0,0,0,1,0,0,0,0,0],
                 [0,0,0,0,1,1,1,0,0,0,0],
                 [1,1,1,1,1,1,1,1,1,1,1],
                 [1,1,1,1,1,1,1,1,1,1,1],
                 [1,1,1,1,1,1,1,1,1,1,1],
                 [1,1,1,0,0,0,0,0,1,1,1]],
                [0x00000000, 0xffAAAAAA]
            );
        }
        
    public function saucerBmd():BitmapData
        {
            return BitmapPatternBuilder.build(
                [[0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0],
                 [0,0,0,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0],
                 [0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0],
                 [0,0,0,0,1,1,1,1,0,1,1,0,1,1,1,1,0,0,0,0],
                 [1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1],
                 [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
                 [0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0],
                 [0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0]],
                [0x00000000, 0xff990033]
            );
        }
        
/********************************************
* keyDownHandler - keyboard handler
*********************************************/   
        public function keyDownHandler(e:KeyboardEvent):void 
        {
            switch(e.keyCode)
            {//Set flags for key presses
                case Keyboard.LEFT:
                    leftFlag = true;
                    break;
                case Keyboard.RIGHT: 
                    rightFlag = true;
                    break;
                case Keyboard.SPACE:
                                case Keyboard.UP:
                    spaceFlag = true;
                    break;
                default:
            }
        }

/********************************************
* keyUpHandler - keyboard handler
*********************************************/         
        public function keyUpHandler(e:KeyboardEvent):void {
            switch(e.keyCode)
            {//Kill flags for the right key up
                case Keyboard.LEFT:
                    leftFlag = false;
                    break;
                case Keyboard.RIGHT: 
                    rightFlag = false;
                    break;
                case Keyboard.SPACE:
                                case Keyboard.UP:
                    spaceFlag = false;
                    break;
                default:
            }
        }
    }
}

/**-----------------------------------------------------
 * Use following BitmapPatternBuilder class 
 * 
 * DO NOT CHANGE any codes below this comment.
 *
 * -----------------------------------------------------
*/
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();        
    }
}