From 5520d1e41bacb2b485bd1395a04408903f491b18 Mon Sep 17 00:00:00 2001 From: Hans Kokx Date: Sun, 30 Aug 2026 14:12:28 +0200 Subject: [PATCH] Rename some variables for clarity; add variables for game size. Signed-off-by: Hans Kokx --- raycaster.c | 213 +++++++++++++++++++++++++++------------------------- 1 file changed, 109 insertions(+), 104 deletions(-) diff --git a/raycaster.c b/raycaster.c index 5a86b74..a3b7c61 100644 --- a/raycaster.c +++ b/raycaster.c @@ -7,14 +7,18 @@ #define PI3 3 * PI / 2 #define DR 0.0174533f // One degree in radians +#define gameHeight 160 +#define gameWidth 320 +#define aspectRatio 3.2 + // 0° => 0 radians (RIGHT) // 90° => π/2 radians (TOP) // 180° => π radians (LEFT) // 270° => 3π/2 radians (BOTTOM) // 360° => 2π radians (RIGHT) -// * Player position (px, py), delta (pdx, pdy), and angle (pa) -float px, py, pdx, pdy, pa; +// * Player position (playerX, playerY), delta (pdx, pdy), and angle (pa) +float playerX, playerY, pdx, pdy, playerAngle; // * Draw the player on the screen void drawPlayer() @@ -23,14 +27,14 @@ void drawPlayer() glColor3f(1, 1, 0); glPointSize(8); glBegin(GL_POINTS); - glVertex2i(px, py); + glVertex2i(playerX, playerY); glEnd(); // Draws the player direction glLineWidth(3); glBegin(GL_LINES); - glVertex2i(px, py); - glVertex2i(px + pdx * 5, py + pdy * 5); + glVertex2i(playerX, playerY); + glVertex2i(playerX + pdx * 5, playerY + pdy * 5); glEnd(); } @@ -59,8 +63,8 @@ void drawMap2D() { for (x = 0; x < mapX; x++) { - // Check if it's a wall (e.g., 1) - if (map[y * mapX + x] == 1) + // Check if it's a wall + if (map[y * mapX + x] > 0) { // Color walls (white) glColor3f(1, 1, 1); @@ -96,10 +100,10 @@ float dist(float ax, float ay, float bx, float by, float ang) // * The actual raycaster void drawRays3D() { - int r, mx, my, mp, dof; + int r, mx, my, mapPoint, dof; // Ray x, y, angle - float rx, ry, ra; + float rayX, rayY, rayAngle; float xo, yo; @@ -108,16 +112,16 @@ void drawRays3D() // Let's initialize the ray angle n degrees from the player's facing position // ra = ray angle; pa = player angle; DR = degree radian; n = degrees to use - ra = pa - DR * 30; + rayAngle = playerAngle - DR * 30; // Make sure to limit the next angle - if (ra < 0) + if (rayAngle < 0) { - ra += 2 * PI; + rayAngle += 2 * PI; } - if (ra > 2 * PI) + if (rayAngle > 2 * PI) { - ra -= 2 * PI; + rayAngle -= 2 * PI; } // * Cast n rays @@ -129,25 +133,25 @@ void drawRays3D() // We need to get the shortest ray cast in either the vertical or horizontal // distance. So, we'll set a default that's way higher than we'll ever // calculate, and save the horizontal ray's X and Y position. - float disH = 1000000, hx = px, hy = py; + float distanceHor = 1000000, hx = playerX, hy = playerY; // Negative inverse of tangent - float aTan = -1.0f / tanf(ra); + float aTan = -1.0f / tanf(rayAngle); // Check if the ray is looking up or down. // If it's less than π (e.g., 180°), we're looking down. // ? Looking up (ray angle > π) - if (ra > PI) + if (rayAngle > PI) { // Round the ray's Y position to the nearest 64th value. // We can do this by bit-shifting down by 6, then bit-shifting back up by // 6. Then, we subtract a small amount for accuracy. - ry = (((int)py >> 6) << 6) - 0.0001f; + rayY = (((int)playerY >> 6) << 6) - 0.0001f; // The ray's X value is the distance between the player and the ray's Y // position, times the inverse of tangent, plus the player's X position. - rx = (py - ry) * aTan + px; + rayX = (playerY - rayY) * aTan + playerX; // Now that we have the ray's first grid intersection position, we need // the next X and Y offset for the second grid intersection point. @@ -156,13 +160,13 @@ void drawRays3D() } // ? Looking down - if (ra < PI) + if (rayAngle < PI) { // This is almost exactly the same as looking up, but we add one grid // unit, instead of subtracting a tiny amount. - ry = (((int)py >> 6) << 6) + 64; + rayY = (((int)playerY >> 6) << 6) + 64; - rx = (py - ry) * aTan + px; + rayX = (playerY - rayY) * aTan + playerX; // This is almost exactly the same as looking up, but we add instead of // subtract. @@ -171,11 +175,11 @@ void drawRays3D() } // ? Looking straight left or right - if (ra == 0.0f || ra == PI) + if (rayAngle == 0.0f || rayAngle == PI) { // It's impossible to ever hit a horizontal line - rx = px; - ry = py; + rayX = playerX; + rayY = playerY; } int mv = 0, mh = 0; @@ -188,23 +192,23 @@ void drawRays3D() // to know where that is in the map array. // Let's take the ray hit position (rx,ry) and divide it by 64 (bit-shift // 6 places), and use that to find the position in the map's array. - mx = (int)(rx) >> 6; - my = (int)(ry) >> 6; - mp = my * mapX + mx; + mx = (int)(rayX) >> 6; + my = (int)(rayY) >> 6; + mapPoint = my * mapX + mx; // If the map position is less than the array's size, then we can check it // inside the map. If the value is 1, there's a wall. If we hit a wall, // we're done! - if (mp > 0 && mp < mapX * mapY && map[mp] > 0) + if (mapPoint > 0 && mapPoint < mapX * mapY && map[mapPoint] > 0) { // We hit a wall! - mh = map[mp]; + mh = map[mapPoint]; // Save the values and calculate the distance from the player - hx = rx; - hy = ry; - disH = dist(px, py, hx, hy, ra); + hx = rayX; + hy = rayY; + distanceHor = dist(playerX, playerY, hx, hy, rayAngle); dof = 8; // Break the loop - no need to calculate more. } @@ -212,42 +216,42 @@ void drawRays3D() { // If we didn't hit a wall, we check the next horizontal line by adding // the x and y offset. - rx += xo; - ry += yo; + rayX += xo; + rayY += yo; dof += 1; } } // * --- Check Vertical Lines --- dof = 0; - float disV = 1000000, vx = px, vy = py; + float distanceVert = 1000000, vx = playerX, vy = playerY; // Negative of tangent - float nTan = -tanf(ra); + float nTan = -tanf(rayAngle); // ? Looking left - if (ra > PI2 && ra < PI3) + if (rayAngle > PI2 && rayAngle < PI3) { - rx = (((int)px >> 6) << 6) - 0.0001f; - ry = (px - rx) * nTan + py; + rayX = (((int)playerX >> 6) << 6) - 0.0001f; + rayY = (playerX - rayX) * nTan + playerY; xo = -64; yo = -xo * nTan; } // ? Looking right - if (ra < PI2 || ra > PI3) + if (rayAngle < PI2 || rayAngle > PI3) { - rx = (((int)px >> 6) << 6) + 64; - ry = (px - rx) * nTan + py; + rayX = (((int)playerX >> 6) << 6) + 64; + rayY = (playerX - rayX) * nTan + playerY; xo = 64; yo = -xo * nTan; } // ? Looking straight up or down - if (ra == 0.0f || ra == PI) + if (rayAngle == 0.0f || rayAngle == PI) { - rx = px; - ry = py; + rayX = playerX; + rayY = playerY; } while (dof < 8) @@ -256,23 +260,23 @@ void drawRays3D() // to know where that is in the map array. // Let's take the ray hit position (rx,ry) and divide it by 64 (bit-shift // 6 places), and use that to find the position in the map's array. - mx = (int)(rx) >> 6; - my = (int)(ry) >> 6; - mp = my * mapX + mx; + mx = (int)(rayX) >> 6; + my = (int)(rayY) >> 6; + mapPoint = my * mapX + mx; // If the map position is less than the array's size, then we can check it // inside the map. If the value is 1, there's a wall. If we hit a wall, // we're done! - if (mp > 0 && mp < mapX * mapY && map[mp] > 0) + if (mapPoint > 0 && mapPoint < mapX * mapY && map[mapPoint] > 0) { // We hit a wall! - mv = map[mp]; + mv = map[mapPoint]; // Save the values and calculate the distance from the player - vx = rx; - vy = ry; - disV = dist(px, py, vx, vy, ra); + vx = rayX; + vy = rayY; + distanceVert = dist(playerX, playerY, vx, vy, rayAngle); dof = 8; // Break the loop - no need to calculate more. } @@ -280,8 +284,8 @@ void drawRays3D() { // If we didn't hit a wall, we check the next horizontal line by adding // the x and y offset. - rx += xo; - ry += yo; + rayX += xo; + rayY += yo; dof += 1; } } @@ -290,11 +294,11 @@ void drawRays3D() // This is what actually determines our ray that hits a wall! // Vertical wall hit - if (disV < disH) + if (distanceVert < distanceHor) { - rx = vx; - ry = vy; - disT = disV; + rayX = vx; + rayY = vy; + disT = distanceVert; // Vertical walls are drawn a little brighter than horizontal walls glColor3f(0.9, 0, 0); @@ -305,11 +309,11 @@ void drawRays3D() } // Horizontal wall hit - if (disH < disV) + if (distanceHor < distanceVert) { - rx = hx; - ry = hy; - disT = disH; + rayX = hx; + rayY = hy; + disT = distanceHor; // Horizontal walls are drawn a little darker than vertical walls glColor3f(0.7, 0, 0); @@ -322,59 +326,59 @@ void drawRays3D() // * Draw the ray glLineWidth(3); glBegin(GL_LINES); - glVertex2i(px, py); - glVertex2i(rx, ry); + glVertex2i(playerX, playerY); + glVertex2i(rayX, rayY); glEnd(); // * --- Draw 3D Walls --- // Correct the fish-eye effect - float ca = pa - ra; - if (ra < 0) + float correctedAngle = playerAngle - rayAngle; + if (rayAngle < 0) { - ra += 2 * PI; + rayAngle += 2 * PI; } - if (ra > 2 * PI) + if (rayAngle > 2 * PI) { - ra -= 2 * PI; + rayAngle -= 2 * PI; } - disT = disT * cos(ca); + disT = disT * cos(correctedAngle); - // The window will be 320x160 px + // The window will be 320x160 px (windowW x windowH) // The formula for each line height will be the cube size (64) times our - // screen height (320), divided by the ray distance (disT). + // screen height, divided by the ray distance (disT). // The further away, the larger the distance and the shorter the final line // height will be. - float lineH = (mapS * 320) / disT; + float lineHeight = (mapS * gameWidth) / disT; // We need to offset the line to the middle of the screen // That's the full window height, minus half the line height - float lineO = 160 - lineH / 2; + float lineOffset = gameHeight - lineHeight / 2; // Let's make sure the line doesn't exceed our vertical space, so we cap it - if (lineH > 320) + if (lineHeight > gameWidth) { - lineH = 320; + lineHeight = gameWidth; } // * Draw the "wall" line glLineWidth(8); glBegin(GL_LINES); // Draw the line every 8th pixel, and shift the viewport to the right by 530 - glVertex2i(r * 8 + 530, lineO); - glVertex2i(r * 8 + 530, lineH + lineO); + glVertex2i(r * 8 + gameWidth + 210, lineOffset); + glVertex2i(r * 8 + gameWidth + 210, lineHeight + lineOffset); glEnd(); // * Increase the ray angle to draw the next ray - ra += DR; - if (ra < 0) + rayAngle += DR; + if (rayAngle < 0) { - ra += 2 * PI; + rayAngle += 2 * PI; } - if (ra > 2 * PI) + if (rayAngle > 2 * PI) { - ra -= 2 * PI; + rayAngle -= 2 * PI; } } } @@ -401,32 +405,32 @@ void buttons(unsigned char key, int x, int y) // 0° -> 360° ≈ 0 -> ~6.28 // Change player angle slightly (using radians) - pa -= 0.1; + playerAngle -= 0.1; // If player angle drops below 0, let's reset back to 2π - if (pa < 0) + if (playerAngle < 0) { - pa += 2 * PI; + playerAngle += 2 * PI; } // The values returned from sin() and cos() are very small, so we'll just // artificialy inflate them by multilying by 5. This is our actual movement. - pdx = cos(pa) * 5.0f; - pdy = sin(pa) * 5.0f; + pdx = cos(playerAngle) * 5.0f; + pdy = sin(playerAngle) * 5.0f; } // ? Move right if (key == 'd') { - pa += 0.1; + playerAngle += 0.1; - if (pa > 2 * PI) + if (playerAngle > 2 * PI) { - pa -= 2 * PI; + playerAngle -= 2 * PI; } - pdx = cos(pa) * 5.0f; - pdy = sin(pa) * 5.0f; + pdx = cos(playerAngle) * 5.0f; + pdy = sin(playerAngle) * 5.0f; } // ? Move forward @@ -434,15 +438,15 @@ void buttons(unsigned char key, int x, int y) { // We change the X and Y values based on our delta, which is calculated // during our rotation. - px += pdx; - py += pdy; + playerX += pdx; + playerY += pdy; } // ? Move backwards if (key == 's') { - px -= pdx; - py -= pdy; + playerX -= pdx; + playerY -= pdy; } glutPostRedisplay(); } @@ -453,15 +457,16 @@ void init() glClearColor(0.3, 0.3, 0.3, 0); // Sets the window to be 2D at a given size - gluOrtho2D(0, 1024, 512, 0); + // gluOrtho2D(0, 1024, 512, 0); + gluOrtho2D(0, gameWidth * aspectRatio, gameHeight * aspectRatio, 0); // Set the initial player location - px = 300; - py = 300; + playerX = 300; + playerY = 300; // Calculate the initial player deltaX and deltaY - pdx = cos(pa) * 5.0f; - pdy = sin(pa) * 5.0f; + pdx = cos(playerAngle) * 5.0f; + pdy = sin(playerAngle) * 5.0f; } int main(int argc, char *argv[])