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: Ray casting test

Using Distance-Function ( http://iquilezles.org/www/articles/distfunctions/distfunctions.htm )
a little faster, more accurate.
Get Adobe Flash player
by phi16 08 May 2014

    Talk

    hemingway at 08 May 2014 19:02
    this looks like a great a solution, any drawbacks to relying on dist vs ?
    bennett.yeates at 09 May 2014 18:38
    Excellent addition! That's exactly what it was missing
    phi16 at 10 May 2014 15:35
    I think this method can't be used for representation of picture or realistic objects because calculation of the distance is difficult and slow. but can for composite or repetitive or mathematical object, easily.
    Embed
/**
 * Copyright phi16 ( http://wonderfl.net/user/phi16 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ix4Y
 */

// forked from bennett.yeates's Ray casting test
package
{
    import flash.utils.Proxy;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.geom.Point;
    import flash.ui.Keyboard;

    [SWF(backgroundColor=0x0)]
    public class RayCastTest extends Sprite
    {
        private const FOV            :int = 60;
        private const STEP_LENGTH    :int = 5; //length of the ray to step by
        
        private var player            :Sprite;
        
        private var ray_drawer        :Sprite;
        private var dist_drawer       :Sprite;
        private var squares           :Array = [];
        private const POSITIONS:Array = [ {x:0, y:0}, {x:0, y:stage.stageHeight/2}, {x:stage.stageWidth-100, y:stage.stageHeight/2 - 50}, 
                                          {x:stage.stageWidth/2, y:stage.stageHeight - 100}, {x:stage.stageWidth-100, y:stage.stageHeight - 100} ];
        public function RayCastTest()
        {
            ray_drawer = new Sprite();
            dist_drawer = new Sprite();
            
            var i:int;
            for ( ; i < 5; ++i ) {
                var square:Sprite = new Sprite();
                square.graphics.beginFill(0);
                square.graphics.drawRect(0,0,100,100);
                
                square.x = POSITIONS[i].x;
                square.y = POSITIONS[i].y;
                
                addChild( square );    
                squares.push( square );
            }
            player = new Sprite();
            player.graphics.beginFill(0x0000FF);
            player.graphics.drawRect(0,0,5,5);
            
            player.x = stage.stageWidth/2 - 2.5;
            player.y = stage.stageHeight/2 - 2.5;
            addChild( player );
            addChild( ray_drawer );
            addChild( dist_drawer );
                        
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
            addEventListener( Event.ENTER_FRAME, oef );
        }
        
        public function onKeyDown( e:KeyboardEvent ):void {
            if ( e.keyCode == Keyboard.LEFT ) { player.rotation -= 2; }
            else if ( e.keyCode == Keyboard.RIGHT ) { player.rotation += 2; }
        }
        public function distance(p:Point) : Number {
            var l:Number=-1;
            for(var i:int=0;i<squares.length;i++){
                var square:Sprite = squares[i];
                var pos:Point = new Point(square.x+50,square.y+50);
                
                var ps:Point = new Point(p.x-pos.x,p.y-pos.y);
                ps.x=Math.abs(ps.x)-50,ps.y=Math.abs(ps.y)-50;
                
                var len:Number=Math.min(Math.max(ps.x,ps.y),0);
                ps.x=Math.max(ps.x,0),ps.y=Math.max(ps.y,0);
                len+=Math.sqrt(ps.x*ps.x+ps.y*ps.y);
                
                if(i==0 || len<l)l=len;
            }
            return l;
        }

        public function oef( e:Event ):void {
            ray_drawer.graphics.clear();
            dist_drawer.graphics.clear();
            ray_drawer.graphics.lineStyle( 2, 0xFF0000 , 0.3 );
            dist_drawer.graphics.lineStyle( 2, 0x0000FF );
            
            var startRotation:Number = player.rotation - FOV/2;
            var endRotation:Number = player.rotation + FOV/2;
            
            var hit:Boolean;
            var length:Number;
            var center:Boolean=true;
            while( startRotation < endRotation ) {
                center = Math.abs(startRotation-player.rotation)<1.0;
                if(center)ray_drawer.graphics.lineStyle( 2, 0xFF0000 );
                hit = false;
                                
                var pos:Point = new Point( player.x, player.y );
                while( !hit ) {
                    length = distance(pos);
                    if(center){
                        dist_drawer.graphics.drawCircle(pos.x,pos.y,length);
                    }
                    pos.x += length * Math.cos( startRotation * Math.PI / 180 );
                    pos.y += length * Math.sin( startRotation * Math.PI / 180 );
                    if(length <= 0.01 )hit=true;
                    if ( pos.x >= stage.stageWidth || pos.x < 0 || pos.y < 0 || pos.y >= stage.stageHeight ) {
                        hit = true;
                    }
                }
                ray_drawer.graphics.moveTo( player.x, player.y );
                ray_drawer.graphics.lineTo( pos.x, pos.y );
                ++startRotation;
                if(center)ray_drawer.graphics.lineStyle( 2, 0xFF0000 , 0.3 );
            }
        }
    }
}