Simple missile tracking system

by sindney
Click on any box to set him as a target.
Have fun !

@author sindney, makc
@version 1.0
@date 07.16.2010
♥0 | Line 116 | Modified 2010-07-16 22:00:19 | MIT License
play

ActionScript3 source code

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

package {
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.events.MouseEvent;
    import flash.events.Event;

    import sandy.core.Scene3D;
    import sandy.core.scenegraph.*;
    import sandy.materials.Appearance;
    import sandy.materials.ColorMaterial;
    import sandy.materials.attributes.MaterialAttributes;
    import sandy.materials.attributes.LineAttributes;

    import sandy.primitive.Box;
    import sandy.primitive.Plane3D;

    import sandy.events.Shape3DEvent;

    /**
     * Click on any box to set him as a target.
     * Have fun !
     * 
     * @author sindney, makc
     * @version 1.0
     * @date 07.16.2010
     */
    [SWF(width = "465", height = "465", frameRate = "30", backGroundColor = "#0066cc")]
    public class Main extends Sprite {
        
        private var _m:Missile3D;
        private var _statu:TextField = new TextField();

        private var g:Group;
        private var camera:Camera3D;
        private var scene:Scene3D;
        
        public function Main() {
            stage.quality = "low";
            
            graphics.beginFill(0x0066CC);
            graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
            graphics.endFill();
            
            camera = new Camera3D(stage.stageWidth,stage.stageHeight);
            g = new Group();
            scene = new Scene3D("scene",this,camera,g);
            camera.y = 400;
            
            var _ma:MaterialAttributes = new MaterialAttributes( new LineAttributes() );

            //add boxes
            for (var i:int = 0; i < 30; i++) {
                var box:Box = new Box("box_" + i,30,30,30,"quad",1);
                box.rotateX = Math.random() * 360;
                box.rotateY = Math.random() * 360;
                box.x = -400 + Math.random() * 800;
                box.z = -400 + Math.random() * 800;
                box.y = 5 + Math.random() * 50;
                box.appearance = new Appearance(new ColorMaterial(Math.floor(0xFFFFFF * Math.random())));
                box.appearance.frontMaterial.attributes = _ma;
                box.enableEvents = true;
                box.addEventListener(MouseEvent.MOUSE_DOWN, switchTarget );
                g.addChild( box );
            }
            //add plane
            var _p:Plane3D = new Plane3D( "myPlane", 800, 800, 5, 5, Plane3D.ZX_ALIGNED );
            _p.appearance = new Appearance(new ColorMaterial(Math.floor(0xFFFFFF * Math.random())));
            _p.appearance.frontMaterial.attributes = _ma;
            _p.enableForcedDepth = true;
            _p.forcedDepth = 1000;
            g.addChild(_p);

            //add missile
            _m = new Missile3D("myMissile");
            _m.myTarget = g.getChildByName("box_0") as Shape3D;
            g.addChild(_m);

            //add statuBox
            _statu.width = 200;
            _statu.text = "myMissile following:box_0";
            addChild(_statu);

            addEventListener( Event.ENTER_FRAME, render );
        }
        private function switchTarget(e:Shape3DEvent):void {
            _m.myTarget = e.shape;
            _statu.text = _m.toString();
        }
        private function render(e:Event):void {
            _m.move(5);
            camera.lookAt(_m.x,_m.y,_m.z);
            scene.render();
        }
    }
}

import sandy.util.NumberUtil;
import sandy.core.data.Vertex;

import sandy.primitive.Box;
import sandy.core.scenegraph.Shape3D;
import sandy.materials.Appearance;
import sandy.materials.ColorMaterial;
    
class Missile3D extends Box {
    
    private var _target:Shape3D = null;
    
    public function Missile3D ( _n:String ) {
        super(_n,5,5,20);
            
        var _a1:Appearance = new Appearance(new ColorMaterial(0xff0000));
        var _a2:Appearance = new Appearance(new ColorMaterial(0xffffff));
        var _a3:Appearance = new Appearance(new ColorMaterial(0x000000));
            
        getFace(0).appearance = _a1;
        getFace(1).appearance = _a3;
        getFace(2).appearance = _a2;
        getFace(3).appearance = _a2;
        getFace(4).appearance = _a2;
        getFace(5).appearance = _a2;
    }
        
    public function get myTarget():Shape3D {
        return _target;
    }
    public function set myTarget(_v:Shape3D):void {
         _target = _v;
    }
    
    //rotation limit
    private const _maxAngle:uint = 4;
    //wonder angle
    private var _wa:int = 0;
    //angle
    private var _a:int = 0;
    
    private var _v2:Vertex;
    private var _v3:Vertex;
    private var _v1:Vertex;
    
    public function move( _v:int ): void{
        if(_target != null){
            _v3 = Vertex.createFromPoint3D(out);
            _v2 = new Vertex(_target.x-x, _target.y-y, _target.z-z);
            _v1 = _v3.cross(_v2);
            
            _wa = NumberUtil.toDegree( _v3.getAngle(_v2) );
            
            _wa <= _maxAngle ? _a = _maxAngle - _wa : _a = _maxAngle;
                
            rotateAxis(_v1.x,_v1.y,_v1.z, _a);
        }
        moveForward(_v);
    }
    
    public override function toString():String {
        return name + " following:" + _target.name;
    }
}