M1 Abrams

by hemingway
M1 Abrams vehicle testing for upcoming 'BF2D' built with Starling & Nape

Input:

W = accelerate forward
S = accelerate backward
A = pivot left
D = pivot right

Mouse Move = pivot head to the direction of mouse
Mouse Down = fire ballistic

----------

ballistic is representative of a 'canister shell' which houses multiple projectiles in one shell, upon firing, the projectile produces a spread pattern with the several ballistics

single shell performs the same function, just adds only one ballistic instead of multiple.

in the future you may alternate between different firing modes
♥3 | Line 341 | Modified 2013-06-20 07:29:15 | MIT License
play

ActionScript3 source code

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

package
{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.net.*;
    
    import nape.phys.*;
    import nape.geom.*;
    import nape.util.*;
    import nape.space.*;
    import nape.shape.*;
    import nape.callbacks.*;
    
    import net.hires.debug.*;
    
    [SWF(frameRate=60, width=465, height=465)]
    public class M1 extends Sprite
    {
        protected var action :int;
        
        private var tankHead :Sprite;
        private var tankBarrel :Sprite;
        private var tankBody :Sprite;
        private var tankBallistic :Projectile;
        private var tankDimensions :Array;
        
        /*
            [0] = head width
            [1] = head height
            [2] = barrel width
            [3] = barrel height
            [4] = body width
            [5] = body height
        */
        
        private var barrelRecoil :Boolean;
        
        private var KEY_W :Boolean;
        private var KEY_A :Boolean;
        private var KEY_S :Boolean;
        private var KEY_D :Boolean;
        
        public function M1()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;            
            
            Buffer.STAGE = stage;
            Buffer.SPACE = new Space();
            Buffer.ROOT = this;
            
            tankHead = new Sprite();
            tankBarrel = new Sprite();
            tankBody = new Sprite();
            tankDimensions = [24, 20, 32, 4, 48, 28];
            
            barrelRecoil = false;
            
            KEY_W = KEY_A = KEY_S = KEY_D = false;

            x = 232.5;
            y = 232.5;
            
            addEventListener(Event.ADDED_TO_STAGE, addedToStage);
            addEventListener(Event.ENTER_FRAME, Buffer.updateNape);
        }
        
        private function addedToStage($e:*) :void
        {
            removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
            
            addChild(tankBody);
            addChild(tankBarrel);
            addChild(tankHead);
 
            init();
            
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
            stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
            addEventListener(Event.ENTER_FRAME, onFrame);
        }
        
        private function init() :void
        {
            initHead();
            initBarrel();
            initBody();
        }

        private function initHead() :void
        {
            var $width :int = tankDimensions[0];
            var $height :int = tankDimensions[1];
            var $a :int = ($width/2);
            var $b :int = ($height/2);

            tankHead.graphics.lineStyle(1);
            tankHead.graphics.beginFill(0xFFFFFF);
            
            tankHead.graphics.moveTo (-$a, -$b);
            tankHead.graphics.lineTo (($a - $a), -$b);
            tankHead.graphics.lineTo (($a - 4), -$b); 
            tankHead.graphics.lineTo ($a, ((-$b) + 8)); 
            tankHead.graphics.lineTo ($a, ($b - 8)); 
            tankHead.graphics.lineTo (($a - 4), $b);
            tankHead.graphics.lineTo (-$a, $b); 
            tankHead.graphics.lineTo (-$a, -$b);
            
            tankHead.graphics.endFill();
        }
        
        private function initBarrel() :void
        {
            var $width :int = tankDimensions[2];
            var $height :int = tankDimensions[3];
            var $a :int = ($width/2);
            var $b :int = ($height/2);
            var $c :int = ($a*2);
            var $d :int = ($b/2);
            
            tankBarrel.graphics.clear();
            tankBarrel.graphics.lineStyle(1);
            tankBarrel.graphics.beginFill(0x999999);
            
            tankBarrel.graphics.moveTo (0, -$d);
            tankBarrel.graphics.lineTo ($a, -$d);
            tankBarrel.graphics.lineTo ($a, -$b);
            tankBarrel.graphics.lineTo (($a + 4), -$b);
            tankBarrel.graphics.lineTo (($a + 4), $b);
            tankBarrel.graphics.lineTo ($a, $b);
            tankBarrel.graphics.lineTo ($a, $d);
            tankBarrel.graphics.lineTo (0, $d);
            tankBarrel.graphics.moveTo ($a, -$d);
            tankBarrel.graphics.lineTo ($c, -$d);
            tankBarrel.graphics.lineTo ($c, $d);
            tankBarrel.graphics.lineTo ($a, $d);
            
            tankBarrel.graphics.endFill();
        }
        
        private function initBody() :void
        {
            var $width :int = tankDimensions[4];
            var $height :int = tankDimensions[5];
            var $a :int = ($width/2);
            var $b :int = ($height/2);
            
            tankBody.graphics.lineStyle(1);
            tankBody.graphics.beginFill(0xDCDCDC);
            
            tankBody.graphics.moveTo (-$a, -$b);
            tankBody.graphics.lineTo ($a, -$b);
            tankBody.graphics.lineTo ($a, (-$b + 8));
            tankBody.graphics.lineTo (($a - 2), (-$b + 8));
            tankBody.graphics.lineTo (($a - 2), ($b - 8));
            tankBody.graphics.lineTo ($a, ($b - 8));
            tankBody.graphics.lineTo ($a, $b);
            tankBody.graphics.lineTo (-$a, $b);
            tankBody.graphics.lineTo (-$a, ($b - 8));
            tankBody.graphics.lineTo ((-$a + 2), ($b - 8));
            tankBody.graphics.lineTo ((-$a + 2), (-$b + 8));
            tankBody.graphics.lineTo (-$a, (-$b + 8));
            
            tankBody.graphics.endFill();
        }
        
        private function initBallistic($num:Number = 1) :void
        {
            for (var $:int = 0; $<$num; $++)
            {
                //prepare to fire the ballistic from the barrel
                tankBallistic = new Projectile(tankHead.x, tankHead.y,
                                           int(Math.cos(degreeToRadian(tankBarrel.rotation))*4096),
                                           int(Math.sin(degreeToRadian(tankBarrel.rotation))*4096));
        
                //fire the ballistic
                addChildAt(tankBallistic, 1);
            }
            
            recoilBarrel();
        }
        
        private function recoilBarrel() :void
        {
            tankDimensions[2] = 20;
            initBarrel();
            barrelRecoil = true;
        }

        private function recoverBarrel() :void
        {
            if (tankDimensions[2] < 32)
            {
                tankDimensions[2]++;
                initBarrel();    
            }else{
                barrelRecoil = false;
            }
        }
        
        private function onMouseDown($e:MouseEvent) :void
        {
            action = 2;
        }
        
        private function onKeyDown($e:KeyboardEvent) :void
        {
            switch($e.keyCode)
            {
                case 87:
                    KEY_W = true;
                break;
                
                case 65:
                    KEY_A = true;
                break;
                
                case 83:
                    KEY_S = true;
                break;
                
                case 68:
                    KEY_D = true;
                break;
            }
        }
        
        private function onKeyUp($e:KeyboardEvent) :void
        {
            switch($e.keyCode)
            {
                case 87:
                    KEY_W = false;
                break;
                
                case 65:
                    KEY_A = false;
                break;
                
                case 83:
                    KEY_S = false;
                break;
                
                case 68:
                    KEY_D = false;
                break;              
            }
        }
        
        private function onFrame($e:*) :void
        {
            switch (action)
            {
                case 0:
                    //idle
                break;
                
                case 1:
                    initBallistic();
                break;
                
                case 2:
                    initBallistic(3);
                break;            
            }
            
            if (KEY_W)
            {
                x += Math.cos(degreeToRadian(tankBody.rotation))*1;
                y += Math.sin(degreeToRadian(tankBody.rotation))*1;
            }
            if (KEY_A)
            {
                if (KEY_S)
                {
                    tankBody.rotation++;
                }else{
                    tankBody.rotation--;
                }
            }
            if (KEY_S)
            {
                x -= Math.cos(degreeToRadian(tankBody.rotation))*1;
                y -= Math.sin(degreeToRadian(tankBody.rotation))*1;
            }
            if (KEY_D)
            {
                if (KEY_S)
                {
                    tankBody.rotation--;
                }else{
                    tankBody.rotation++;
                }
            }
            
            (barrelRecoil) ? recoverBarrel() : null;
            
            action = 0;
        }
        
        private function onMouseMove($e:MouseEvent) :void
        {
            tankHead.rotation = tankBarrel.rotation = Buffer.cartesianToPolar(new Point($e.stageX, $e.stageY));
        }
        
        private function degreeToRadian($value:Number) :Number
        {
            return($value * (Math.PI / 180));
        }
    }
}

import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.net.*;

import nape.phys.*;
import nape.geom.*;
import nape.util.*;
import nape.space.*;
import nape.shape.*;
import nape.callbacks.*;

class Projectile extends Sprite
{
    protected var _x :Number;
    protected var _y :Number;
    protected var _vX :Number;
    protected var _vY :Number;
    protected var _angle :int;
        
    private var body :Body;
        
    public function Projectile($x:Number, $y:Number, $vX:Number = 0, $vY:Number = 0)
    {
        _x = $x;
        _y = $y;
        _vX = $vX;
        _vY = $vY;
        
        body = new Body(BodyType.DYNAMIC);
        
        addEventListener(Event.ENTER_FRAME, onFrame);
        
        init();
    }
    
    private function init() :void
    {
        graphics.clear();
        graphics.beginFill(0);
        graphics.lineStyle(1);
        graphics.drawCircle(0, 0, 1);
        graphics.endFill();
        
        body.mass = 0.25;
        body.isBullet = true;
        body.shapes.add(new Circle(1));
        body.space = Buffer.SPACE;
        body.userData.graphic = this;
        body.userData.graphicUpdate = function (body:Body) :void
        {
            body.userData.graphic.rotation = ((body.rotation * 180)/Math.PI);
            body.userData.graphic.x = body.position.x;
            body.userData.graphic.y = body.position.y;
        }
        body.position.setxy(_x, _y);
        action();
    }
    
    private function onFrame($e:*) :void
    {
        disposal(); 
    }
    
    public function action() :void
    {
        body.velocity = Vec2.weak(_vX, _vY);
    }
    
    private function disposal() :void
    {
        if ((body.position.x < -2500 || body.position.x > 2500 || (body.position.y < -2500 || body.position.y > 2500))) {
            removeEventListener(Event.ENTER_FRAME, onFrame);
            parent.removeChild(this);
            Buffer.SPACE.bodies.remove(body);
            body = null;
        }
    }
}

class Buffer
{
    public static var STAGE :Stage;
    public static var SPACE :Space;
    public static var ROOT :Sprite;
    
    public static function updateNape($e:*) :void
    {
        SPACE.step(1 / STAGE.frameRate);
            
        for (var $:int = 0; $<SPACE.liveBodies.length; $++)
        {
            var $body :Body = SPACE.liveBodies.at($);
                $body.userData.graphicUpdate($body);
        }
    }

    public static function cartesianToPolar($:Point) :Number
    {
        var $angle :Number = (180/Math.PI);
        var $final :Point = $.subtract(new Point(ROOT.x, ROOT.y));
        
        return(Math.atan2($final.y, $final.x) * $angle);
    }
        
    public static function trace($:String) :void
    {
        new LocalConnection().send('we' + ROOT.loaderInfo.parameters.ticket, 'onSendMessageToJS', $+"\n");
    }
}