Sign in to follow this  

Raycasting engine: drawing floor and ceiling

This topic is 2667 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello!

I need some help, I'm a total beginner when it comes to raycasting. I have some raycasting code I need to modify so it also draws floor and ceiling. The complete rendering code is below (written in javascript):


var stripWidth = 3;
var numRays = Math.ceil(screenWidth / stripWidth);
var viewDist = (screenWidth/2) / Math.tan((fov/2));
var twoPI = Math.PI*2;

function renderWalls()
{
var stripIdx = 0;

for (var i = 0; i < numRays; ++i)
{
// Calculate screen position of ray
var rayScreenPos = (-numRays/2 + i) * stripWidth;

// Distance from viewer to screen point
var rayViewDist = Math.sqrt(rayScreenPos*rayScreenPos + viewDist*viewDist);

// Angle of ray relative to viewing direction
var rayAngle = Math.asin(rayScreenPos / rayViewDist);

// Ray's away!
castSingleWallRay(player.rot + rayAngle, stripIdx++);
}
}

function castSingleWallRay(rayAngle, stripIdx)
{
// Make sure the angle is between 0 and 360 degrees
rayAngle %= twoPI;
if (rayAngle < 0) rayAngle += twoPI;

// Moving right/left and/or up/down? Determined by the quadrant the angle is in
var right = (rayAngle > twoPI * 0.75 || rayAngle < twoPI * 0.25);
var up = (rayAngle < 0 || rayAngle > Math.PI);

var wallType = 0;

var angleSin = Math.sin(rayAngle);
var angleCos = Math.cos(rayAngle);

var dist = 0; // Distance to block that was hit
var xHit = 0; // X and Y coord of where the ray hit the block
var yHit = 0;
var xWallHit = 0;
var yWallHit = 0;

var textureX; // The X coord of the texture. Determines which texture to render.
var wallX; // The map coords of the block
var wallY;
var wallIsShaded = false;
var wallIsHorizontal = false;

var slope = angleSin / angleCos;
var dXVer = right ? 1 : -1;
var dYVer = dXVer * slope;

/*
Start by checking against vertical wall lines. This is done by
moving to the right or left edge of the block we're standing in
and then moving in 1 map unit steps horizontally. The amount we
have to move vertically is determined by the slope of the ray.
*/


var x = right ? Math.ceil(player.x) : Math.floor(player.x);
var y = player.y + (x - player.x) * slope;

while (x >= 0 && x < mapWidth && y >= 0 && y < mapHeight)
{
var wallX = (x + (right ? 0 : -1)) >> 0;
var wallY = (y) >> 0;

if (spriteMap[wallY][wallX] && !spriteMap[wallY][wallX].visible)
{
spriteMap[wallY][wallX].visible = true;
visibleSprites.push(spriteMap[wallY][wallX]);
}

// Is the point within a wall?
if (map[wallY][wallX] > 0)
{
var distX = x - player.x;
var distY = y - player.y;
dist = distX*distX + distY*distY; // Distance from player to point

wallType = map[wallY][wallX];
textureX = y % 1; // Where on the wall did we hit?
if (!right) textureX = 1 - textureX; // Flip texture if we are looking to the left

xHit = x; // Hit coords
yHit = y;
xWallHit = wallX;
yWallHit = wallY;
wallIsShaded = true; // Make horizontal walls shaded
wallIsHorizontal = true;

break;
}

x = x + dXVer;
y = y + dYVer;
}

/*
Now check against horizontal lines.
*/


var slope = angleCos / angleSin;
var dYHor = up ? -1 : 1;
var dXHor = dYHor * slope;
var y = up ? Math.floor(player.y) : Math.ceil(player.y);
var x = player.x + (y - player.y) * slope;

while (x >= 0 && x < mapWidth && y >= 0 && y < mapHeight)
{
var wallY = (y + (up ? -1 : 0)) >> 0;
var wallX = (x) >> 0;

if (spriteMap[wallY][wallX] && !spriteMap[wallY][wallX].visible)
{
spriteMap[wallY][wallX].visible = true;
visibleSprites.push(spriteMap[wallY][wallX]);
}

if (map[wallY][wallX] > 0)
{
var distX = x - player.x;
var distY = y - player.y;
var blockDist = distX*distX + distY*distY;

if (!dist || blockDist < dist)
{
dist = blockDist;
xHit = x;
yHit = y;
xWallHit = wallX;
yWallHit = wallY;

wallType = map[wallY][wallX];
textureX = x % 1;
if (up) textureX = 1 - textureX;

wallIsShaded = false;
}
break;
}

x = x + dXHor;
y = y + dYHor;
}

if (dist)
{
var strip = screenStrips[stripIdx];

dist = Math.sqrt(dist);
dist = dist * Math.cos(player.rot - rayAngle);

/*
Calculate position, height and width of wall strip
*/


var height = Math.round(viewDist / dist);
var width = height * stripWidth;
var top = Math.round((screenHeight - height) / 2);

var imgTop = 0;
var style = strip.style;
var oldStyles = strip.oldStyles;
var styleHeight;

if (useSingleTexture)
{
imgTop = (height * (wallType-1))>>0;
var styleHeight = (height * numTextures)>>0;
}
else
{
var styleSrc = wallTextures[wallType-1];

if (oldStyles.src != styleSrc)
{
strip.src = styleSrc;
oldStyles.src = styleSrc
}

var styleHeight = height;
}

if (oldStyles.height != styleHeight)
{
style.height = styleHeight + "px";
oldStyles.height = styleHeight
}

var texX = Math.round(textureX*width);
if (texX > width - stripWidth)
{
texX = width - stripWidth;
}
texX += (wallIsShaded ? width : 0);

var styleWidth = (width*2)>>0;
if (oldStyles.width != styleWidth)
{
style.width = styleWidth +"px";
oldStyles.width = styleWidth;
}

var styleTop = top - imgTop;
if (oldStyles.top != styleTop)
{
style.top = styleTop + "px";
oldStyles.top = styleTop;
}

var styleLeft = stripIdx*stripWidth - texX;
if (oldStyles.left != styleLeft)
{
style.left = styleLeft + "px";
oldStyles.left = styleLeft;
}

var styleClip = "rect(" + imgTop + ", " + (texX + stripWidth) + ", " + (imgTop + height) + ", " + texX + ")";
if (oldStyles.clip != styleClip)
{
style.clip = styleClip;
oldStyles.clip = styleClip;
}

var dwx = xWallHit - player.x;
var dwy = yWallHit - player.y;
var wallDist = dwx*dwx + dwy*dwy;
var styleZIndex = -(wallDist*1000)>>0;
if (styleZIndex != oldStyles.zIndex)
{
strip.style.zIndex = styleZIndex;
oldStyles.zIndex = styleZIndex;
}
}
}




Any help would be greatly appreciated.

Share this post


Link to post
Share on other sites

This topic is 2667 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this