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:

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();
Bookmark/Search this post with:
My advice, start all over.
My advice, start all over.
Post new comment