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 );
}
}
}
}