projectile testing

by hemingway
added nape phys for rigid bodies
♥0 | Line 367 | Modified 2013-05-21 02:58:24 | 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/80sl
 */

package {
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.text.*;
    
    import net.hires.debug.*;
    
    [SWF(frameRate=60, width=465, height=465, backgroundColor=0xFFFFFF)]    
    public class Main extends Sprite
    {
        private var _buffer :Buffer;
        
        public function Main()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            
            addEventListener(Event.ADDED_TO_STAGE, addedToStage);
        
            _buffer = new Buffer();
            Buffer.STAGE = stage;
        }
        
        private function addedToStage($e:*) :void
        {
            removeEventListener(Event.ADDED_TO_STAGE, addedToStage);    

            addChild(_buffer);
            addChild(new Stats());
            
            init();
        }
    
        private function init() :void
        {
        }
    }
}

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

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

class Buffer extends Sprite
{
    public static var STAGE :Stage;
    public static var CONSOLE :Console;
    public static var TARGETS :Array;
    public static var USERS :Array;
    public static var SPACE :Space;
    
    private var _user :User;
    private var _enemy :Enemy;
    private var _enemy1 :Enemy;
    private var _enemy2 :Enemy;
        
    public function Buffer()
    {
        addEventListener(Event.ADDED_TO_STAGE, addedToStage);
        
        CONSOLE = new Console("Projectile Testing\n------------------------");
        SPACE = new Space();
        _user = new User();
        _enemy = new Enemy();
        _enemy1 = new Enemy();
        _enemy2 = new Enemy();
        
        TARGETS = [_enemy, _enemy1, _enemy2];
        USERS = [_user];
    }
    
    private function addedToStage($e:*) :void
    {
        removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
        
        addChild(CONSOLE);
        addChild(_user);
        addChild(_enemy);
        addChild(_enemy1);
        addChild(_enemy2);
        
        addEventListener(Event.REMOVED, onRemove);
        addEventListener(Event.ENTER_FRAME, updateNape);
    }
    
    private function onRemove($e:*) :void
    {
        CONSOLE.content = "DRW: "+this.numChildren;    
    }
    
    private function updateNape($e:Event) :void
    {
        SPACE.step(1 / stage.frameRate);
            
        for (var $:int = 0; $<SPACE.liveBodies.length; $++)
        {
            var $body :Body = SPACE.liveBodies.at($);
                $body.userData.graphicUpdate($body);
        }
    }
}

class User extends Sprite
{
    protected var _projectile :Projectile;
    protected var _barrelX :Number;
    protected var _target :Object;
    protected var _speed :Number;
    protected var _angle :int
    
    private var tick :int;
    
    public function User($x:Number = 232.5, $y:Number = 232.5)
    {
        addEventListener(Event.ADDED_TO_STAGE, addedToStage);
        
        x = $x;
        y = $y;

        _barrelX = 16;
        _target = null;
        _speed = 2048;
        
        tick = 0;
    }
    
    private function addedToStage($e:*) :void
    {
        removeEventListener(Event.ADDED_TO_STAGE, addedToStage);

        init();
    
        stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
        stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        addEventListener(Event.ENTER_FRAME, determineTargets);
    }
    
    private function init() :void
    {
        graphics.clear();
        graphics.beginFill(0);
        graphics.drawCircle(0, 0, 5.5);
        graphics.endFill();
        
        graphics.beginFill(0);
        graphics.drawRect(-2.5, -2.5, _barrelX, 5);
        graphics.drawRect(-3.5, -3.5, int(_barrelX*0.8575), 7);
        graphics.endFill();
    }
    
    private function onMouseDown($e:MouseEvent) :void
    {   
        //addProjectile(3);
    }
    
    private function onMouseMove($e:MouseEvent) :void
    {
        rotation = cartesianToPolar(new Point($e.stageX, $e.stageY));
    }
    
    private function onFrame($e:*) :void
    {
        (barrel < 16) ? barrel+=0.5 : removeEventListener(Event.ENTER_FRAME, onFrame);
    } 
    
    private function determineTargets($e:*) :void
    {
        tick++
        
        var $targets :Array = [];
            $targets = Buffer.TARGETS;
        var $candidate :Vec2;
        var $velocity :Vec2;
            $velocity = $targets[0].velocity;
        
        $candidate = new Vec2(($targets[0].x + ($velocity.x*0.15)), ($targets[0].y + ($velocity.y*0.15)));
        rotation = cartesianToPolar(new Point($candidate.x, $candidate.y));
        ((tick % 60) == 0) ? (addProjectile(3), barrel = 10, addEventListener(Event.ENTER_FRAME, onFrame)) : null;
    }
    
    private function addProjectile($quantity:int = 1) :void
    {
        for (var $:int = 1; $<=$quantity; $++)
        {
            _projectile = new Projectile(x, y);
            _projectile.vX = int(Math.cos(degreeToRadian(rotation))*_speed);
            _projectile.vY = int(Math.sin(degreeToRadian(rotation))*_speed);
        
            parent.addChild(_projectile);    
        }
    }
    
    private function cartesianToPolar($:Point) :Number
    {
        var $angle :Number = (180/Math.PI);
        var $final :Point = $.subtract(new Point(x, y));
        
        return(Math.atan2($final.y, $final.x) * $angle);
    }
    
    public function degreeToRadian($value:Number) :Number
    {
        return($value * (Math.PI / 180));
    }

    public function get barrel() :Number
    {return _barrelX}
    public function get target() :Object
    {return _target}
    public function get angle() :Number
    {return _angle}
    
    public function set barrel($:Number) :void
    {_barrelX = $; init()}
    public function set target($:Object) :void
    {_target = $; init()}
}

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;
    private var actionTrigger :Boolean;
    
    public function Projectile($x:Number, $y:Number)
    {
        addEventListener(Event.ADDED_TO_STAGE, addedToStage);
       
        _x = $x;
        _y = $y;
        _vX = 0;
        _vY = 0;
        
        body = new Body(BodyType.DYNAMIC);
        actionTrigger = false;
    }
    
    private function addedToStage($e:*) :void
    {
        removeEventListener(Event.ADDED_TO_STAGE, addedToStage);    

        init();
         
        stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
        addEventListener(Event.ENTER_FRAME, onFrame);
    }
    
    private function init() :void
    {
        graphics.clear();
        graphics.beginFill(0);
        graphics.lineStyle(1, 0x0000CC);
        graphics.drawCircle(0, 0, 1.5);
        graphics.endFill();
        
        body.mass = 0.25;
        body.isBullet = true;
        body.shapes.add(new Circle(1.5));
        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);
    }
    
    private function onMouseDown($e:MouseEvent) :void
    {}
    
    private function onFrame($e:*) :void
    {
        (actionTrigger) ? null : action();
        disposal();
    }
    
    private function action() :void
    {
        actionTrigger = true;
        body.velocity = Vec2.weak(vX, vY);
    }
    
    private function cartesianToPolar($:Point) :Number
    {
        var $angle :Number = (180/Math.PI);
        var $final :Point = $.subtract(new Point(x, y));
        
        return(Math.atan2($final.y, $final.x) * $angle);
    }
    
    private function disposal() :void
    {
        if ((body.position.x < 0 || body.position.x > stage.stageWidth) || (body.position.y < 0 || body.position.y > stage.stageHeight)) {
            stage.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            removeEventListener(Event.ENTER_FRAME, onFrame);
            parent.removeChild(this);
            Buffer.SPACE.bodies.remove(body);
            body = null;
        }
    }
    
    public function dot($value1:Point, $value2:Point) :Number
    {
        return (($value1.x * $value2.x) + ($value1.y * $value2.y));
    }
    
    private function sign($:Number) :Boolean
    {
        var $temp :Boolean;
        
        ($ < 0) ? $temp=false : $temp=true;
        
        return($temp);
    }
    
    public function get vX() :Number
    {return _vX}
    public function get vY() :Number
    {return _vY}
    public function get angle() :Number
    {return _angle}
    
    public function set vX($:Number) :void
    {_vX = $; (hasEventListener(Event.ENTER_FRAME)) ? addEventListener(Event.ENTER_FRAME, onFrame) : null}
    public function set vY($:Number) :void
    {_vY = $; (hasEventListener(Event.ENTER_FRAME)) ? addEventListener(Event.ENTER_FRAME, onFrame) : null}
}

class Enemy extends Sprite
{
    protected var _x :Number;
    protected var _y :Number;
    protected var _vX :Number;
    protected var _vY :Number;
    
    private var body :Body;
    
    public function Enemy()
    {
        addEventListener(Event.ADDED_TO_STAGE, addedToStage);
        
        body = new Body(BodyType.DYNAMIC);
        _vX = 24;
        _vY = 0;
    }
    
    private function addedToStage($e:*) :void
    {
        removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
        
        init();
        
        addEventListener(Event.ENTER_FRAME, onFrame);
    }
    
    private function init() :void
    {
        graphics.clear();
        graphics.lineStyle(1);
        graphics.drawCircle(0, 0, 10);
        
        
        body.shapes.add(new Circle(10));
        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(100, 100);
    }
    
    private function onFrame($e:*) :void
    {
        (x < ((465/4)*3)) ? (
            body.velocity = Vec2.weak(_vX, _vY)
        ):(
            body.velocity = Vec2.weak(-_vX, 0)
        );
    }

    public function get vX() :Number
    {return _vX}
    public function get vY() :Number
    {return _vY}
    public function get velocity() :Vec2
    {return body.velocity}
    
    public function set vX($:Number) :void
    {_vX = $; (hasEventListener(Event.ENTER_FRAME)) ? addEventListener(Event.ENTER_FRAME, onFrame) : null}
    public function set vY($:Number) :void
    {_vY = $; (hasEventListener(Event.ENTER_FRAME)) ? addEventListener(Event.ENTER_FRAME, onFrame) : null}
}

class Console extends TextField
{
    private var textFormat :TextFormat;
        
    protected var _x :Number;
    protected var _y :Number;
    protected var _font :String;
    protected var _content :String;
        
    public function Console($content:String, $x:Number = 70, $y:Number = 0, $font:String = "Helvetica")
    {
        addEventListener(Event.ADDED_TO_STAGE, addedToStage);
            
        _x = $x;
        _y = $y;
        _font = $font;
        _content = $content;
            
        multiline = true;
        autoSize = "left";
        selectable = mouseEnabled = false;
        antiAliasType = AntiAliasType.ADVANCED;
    }
    
    private function addedToStage($e:Event) :void
    {
        removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
            
        init(); 
    }
        
    private function init() :void
    {
        x = _x;
        y = _y;
        text = _content;
            
        textFormat = new TextFormat(_font);
        setTextFormat(textFormat);
    }
        
    public function get font() :String
    { return _font }
        
    public function set font($:String) :void
    { _font = $; init() }
    public function set content($:String) :void
    { _content = ($); init() }
}