Writing an 3D Ray Casting Library for PHP

I was inspired by the 3D Ray Casting game, so I decide to write a 3D ray casting engine myself.
First, I have to create a very simple version that only draw wall with one color. and looks like I failed. I will still work on the ray casting system. Can anyone spot why it looks like this? I think I have to work like about another 12 hours on debugging. :noway:
Initial testing result:
Raycasting test No.1
Here is the source:(no highlighting because it make the server slow... and this code is not important...)

	set_time_limit (5);
//error_reporting(0);
	class raycasting{
	var $pov = array('x' => 5, 'y' => 5, 'z' => 32, 'a' => 190);
	var $scale = 64;
	var $fov = 60;
	var $proj = array('w' =>320, 'h' => 200);
	var $map = '';
	var $cons;
 
	function createmap($map){
		$map = explode("\n",$map);
		$i = 0;
		$count = count($map);
		while($i < $count){
			$map[$i] = explode(' ',$map[$i]);
			++$i;
		}
		$this->map = $map;
		}
 
	function iswall($xy){
//	echo 	'x',$xy['x'],'<br />';
//	echo 	'y',$xy['y'],'<br />';
		if($this->map[floor($xy['x']/$this->scale)][floor($xy['y']/$this->scale)]){
			return true;
	}else{
		return false;
	}
	}
 
	function setup(){
		$this->cons['pov2proj'] = abs(0.5*$this->proj['w']/tan(0.5*$this->fov));
		$this->cons['angleinc'] = $this->fov/$this->proj['w'];
		$this->cons['tri_degree'] = 30;
		$this->proj['x'] = floor($this->proj['w']/2);
		$this->proj['y'] = floor($this->proj['h']/2);
		//find type x and y
		if($this->pov['a'] == 0){
			$this->cons['type']['x'] = 1;
			$this->cons['type']['y'] = 0;
		}elseif($this->pov['a'] == 180){
			$this->cons['type']['x'] = -1;
			$this->cons['type']['y'] = 0;
		}elseif($this->pov['a'] == 90){
			$this->cons['type']['x'] = 0;
			$this->cons['type']['y'] = -1;
		}elseif($this->pov['a'] == 270){
			$this->cons['type']['x'] = 0;
			$this->cons['type']['y'] = 1;
		}elseif(90 > $this->pov['a'] && $this->pov['a'] > 0){
			$this->cons['type']['x'] = 1;
			$this->cons['type']['y'] = -1;
		}elseif(180 > $this->pov['a'] && $this->pov['a'] > 90){
			$this->cons['type']['x'] = -1;
			$this->cons['type']['y'] = -1;
		}elseif(270 > $this->pov['a'] && $this->pov['a'] > 180){
			$this->cons['type']['x'] = -1;
			$this->cons['type']['y'] = 1;
		}else{
			$this->cons['type']['x'] = 1;
			$this->cons['type']['y'] = 1;
		}
	}
 
function render(){
	$i = 0;
	while($i < $this->proj['w']){
		//find the x intersect
		//find the y coordinate for the first intersect
		if($this->cons['type']['x'] == 0){
			if($this->cons['type']['y'] == 1){
				$x_intersect['y'] = cell($this->pov['y']/$this->scale)*$this->scale;
			}else{
				$x_intersect['y'] = floor($this->pov['y']/$this->scale)*$this->scale;
			}
		}else{
			if($this->cons['type']['y'] == 1){
				$x_intersect['y'] = floor($this->pov['y']/$this->scale)*$this->scale+$this->scale;
			}else{
				$x_intersect['y'] = floor($this->pov['y']/$this->scale)*$this->scale-1;
			}
		}
		//find the x coordinate of first intersect
		$x_intersect['x'] = floor($this->pov['x'] + ($this->pov['y'] - $x_intersect['y'])/tan($this->cons['tri_degree']));
		//check if it is wall
		if(!$this->iswall($x_intersect)){
			//the loop for intersect that touches the wall
			$y_add = $this->scale * $this->cons['type']['y'];
			$x_add = floor($this->scale/tan($this->cons['tri_degree']));
			while(!$this->iswall($x_intersect)){
				$x_intersect['x'] += $x_add;
				$x_intersect['y'] += $y_add;
			}
		}
 
 
 
 
		//FIND THE Y_INTERSECT THAT TOUCHES A WALL
		//find the y coordinate for the first intersect
		if($this->cons['type']['y'] == 0){
			if($this->cons['type']['x'] == 1){
				$y_intersect['x'] = cell($this->pov['x']/$this->scale)*$this->scale;
 
			}else{
				$y_intersect['x'] = floor($this->pov['x']/$this->scale)*$this->scale;
			}
		}else{
			if($this->cons['type']['x'] == 1){
				$y_intersect['x'] = cell($this->pov['x']/$this->scale)*$this->scale+$this->scale;
 
			}else{
				$y_intersect['x'] = floor($this->pov['x']/$this->scale)*$this->scale-1;
				if($y_intersect['x'] < 0){
					$y_intersect['x'] = 0;
				}
			}
		}
		//find the x coordinate of first intersect
		$y_intersect['y'] = floor($this->pov['y'] + ($this->pov['x'] - $x_intersect['x'])/tan($this->cons['tri_degree']));
		//check if it is wall
		if(!$this->iswall($y_intersect)){
			//the loop for intersect that touches the wall
			$x_add = $this->scale * $this->cons['type']['x'];
			$y_add = floor($this->scale/tan($this->cons['tri_degree']));
			while(!$this->iswall($x_intersect)){
				$y_intersect['x'] += $x_add;
				$y_intersect['y'] += $y_add;
			}
		}
 
		$x_intersect['distance'] = sqrt(pow($this->pov['x']-$x_intersect['x'],2)+pow($this->pov['y']-$x_intersect['y'],2));
		$y_intersect['distance'] = sqrt(pow($this->pov['x']-$y_intersect['x'],2)+pow($this->pov['y']-$y_intersect['y'],2));
		if($x_intersect['distance']<$y_intersect['distance']){
			$distance[$i]['d'] = $x_intersect['distance'];
			$distance[$i]['c'] = 'x';
		}else{
			$distance[$i]['d'] = $y_intersect['distance'];
			$distance[$i]['c'] = 'y';
		}
		++$i;
	}
 
	//remove distortion
	$i = 0;
	$half_fov = $this->fov / 2;
	while($i<$this->proj['x']){
		$product = cos(($this->proj['x']-$i) * $this->cons['angleinc']);
		$distance[$i]['d'] *= $product;
		$distance[$i+$proj['x']]['d'] *= $product;
		++$i;
	}
 
	$product = $this->scale/$this->cons['pov2proj'];
	$i = 0;
	while($i<$this->proj['w']){
		$proj_height[$i] = $product/$distance[$i]['d'];
		++$i;
	}
	//image creation
	$image = imagecreate($this->proj['w'], $this->proj['h']);
	//color
	$god = imagecolorallocate($image, 0xC0, 0xC0, 0xC0);
	$color = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
	$color2 = imagecolorallocate($image, 0x00, 0x00, 0x00);
	//draw wall
	$i = 0;
	while($i < $this->proj['w']){
		$start_y = ($this->proj['h'] - $proj_height[$i])/2;
		imageline($image, $i+1, $start_y, $i+1, $start_y+$proj_height[$i], $color);
		++$i;
	}
header('Content-type: image/png');
header('Content-Length: ' . strlen($img));
	imagepng($image);
}
	}
 
$modle = new raycasting;
$map = 
"1 1 1 1 1 1
1 0 0 0 0 1
1 0 0 0 0 1
1 0 1 1 0 1
1 1 1 1 1 1";
$modle->createmap($map);
$modle->setup();
$modle->render();

My advice, start all over.

serfczar's picture

My advice, start all over.

Post new comment

The content of this field is kept private and will not be shown publicly.
If you have a Gravatar account, used to display your avatar.
  • Allowed HTML tags: <img> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <span> <fn>
  • Lines and paragraphs break automatically.
  • Textual smileys will be replaced with graphical ones.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".
  • Use [fn]...[/fn] (or <fn>...</fn>) to insert automatically numbered footnotes.

More information about formatting options

What is 91 + 6?
To combat spam, please solve the math question above.
Honey Pot that kill bots