I'm implementing a fake 3D rendering using raycasting method (such as Wolfenstein3D). I have following the permandi's tutorial (
But this not always the case. Sometimes it works well, depending the player's orientation.
After rendering the scene in 2D I can see that the rays are indeed not detecting the wall. But depending the orientation, this is not always the case.
On the screenshot above, on the left this is not working but on the right this is working.
This is how I detect the wall and get the distance and the Y axis
float getDistanceOnHorizontalGrid(float rayAngle, float playerPosX, float playerPosY)
{
float pointInRayY = playerPosY (100 * sin(DEGREE_TO_RADIAN(rayAngle))); // Arbitrary Point to evaluate whether ray is facing up or down
float firstIntersectPointY;
float ya;
float xa;
if (pointInRayY <= playerPosY) // ray is facing up
{
firstIntersectPointY = floorf(playerPosY / WALL_SIZE) * (WALL_SIZE)-1;
ya = -WALL_SIZE;
xa = WALL_SIZE / tan(DEGREE_TO_RADIAN(rayAngle)) * -1;
}
else // ray is facing down
{
firstIntersectPointY = floorf(playerPosY / WALL_SIZE) * (WALL_SIZE) WALL_SIZE;
ya = WALL_SIZE;
xa = WALL_SIZE / tan(DEGREE_TO_RADIAN(rayAngle));
}
float firstIntersectPointX = playerPosX - (playerPosY - firstIntersectPointY) / tan(DEGREE_TO_RADIAN(rayAngle));
float nextPointX = firstIntersectPointX;
float nextPointY = firstIntersectPointY;
for (int i = 0; i < MAP_HEIGHT; i )
{
int toMapX = convertWorldToGridCoordinate(floor(nextPointX));
int toMapY = convertWorldToGridCoordinate(floor(nextPointY));
if (!(toMapX >= 0 && toMapX <= MAP_WIDTH - 1 && toMapY >= 0 && toMapY <= MAP_HEIGHT - 1))
{
return 0.0f;
}
if (map[toMapY][toMapX] == 1)
{
return abs(sqrt(((playerPosX - nextPointX) * (playerPosX - nextPointX)) ((playerPosY - nextPointY) * (playerPosY - nextPointY))));
}
nextPointX = xa;
nextPointY = ya;
}
return 0.0f;
}
And the same for X axis
float getDistanceOnverticalGrid(float rayAngle, float playerPosX, float playerPosY)
{
float pointInRayX = playerPosX (100 * cos(DEGREE_TO_RADIAN(rayAngle))); // Arbitrary Point to evaluate whether ray is facing left or right
float firstIntersectX;
float firstIntersectY;
float xa;
float ya;
if (pointInRayX <= playerPosX) // ray facing left
{
firstIntersectX = floorf(playerPosX / WALL_SIZE) * (WALL_SIZE)-1;
xa = -WALL_SIZE;
ya = (WALL_SIZE * tan(DEGREE_TO_RADIAN(rayAngle))) * -1;
}
else
{
firstIntersectX = floorf(playerPosX / WALL_SIZE) * (WALL_SIZE) WALL_SIZE;
ya = WALL_SIZE * tan(DEGREE_TO_RADIAN(rayAngle));
xa = WALL_SIZE;
}
firstIntersectY = playerPosY - (playerPosX - firstIntersectX) * tan(DEGREE_TO_RADIAN(rayAngle));
float nextPointX = firstIntersectX;
float nextPointY = firstIntersectY;
for (int i = 0; i < MAP_WIDTH; i )
{
int toMapX = convertWorldToGridCoordinate(floorf(nextPointX));
int toMapY = convertWorldToGridCoordinate(floorf(nextPointY));
if (!(toMapX >= 0 && toMapX <= (MAP_WIDTH - 1) && toMapY >= 0 && toMapY <= (MAP_HEIGHT - 1)))
{
return 0.0f;
}
if (map[toMapY][toMapX] == 1)
{
return abs(sqrt(((playerPosX - nextPointX) * (playerPosX - nextPointX)) ((playerPosY - nextPointY) * (playerPosY - nextPointY))));
}
nextPointX = xa;
nextPointY = ya;
}
return 0.0f;
}
I must do something wrong, but I don't know where. Thank you for your help
UPDATE
What Mentionned BCT was actually right even though decreasing the value from 1 is still necessary, but not in that calculation. After taking a loog closer to permadi's implementation, after doing this
horizontalGrid = Math.floor(this.fPlayerY/this.TILE_SIZE)*this.TILE_SIZE this.TILE_SIZE;
He did :
horizontalGrid--;
I thought at first it's equal to what I have done but actually no. The reason he decrease the value later it's because this is only to get the grid coordinate.
To resolve my issue, I have removed the -1 from the calculation, and decrease the value only when I'm looking for the grid coordinate.
CodePudding user response:
I looked at the link you sent. And it seems like one of the if blocks has a bad value:
This is the tutorial code:
// Ray is facing down
if (castArc > this.ANGLE0 && castArc < this.ANGLE180)
{
// truncuate then add to get the coordinate of the FIRST grid (horizontal
// wall) that is in front of the player (this is in pixel unit)
// ROUNDED DOWN
horizontalGrid = Math.floor(this.fPlayerY/this.TILE_SIZE)*this.TILE_SIZE this.TILE_SIZE;
This is your code:
if (pointInRayY <= playerPosY) // ray is facing up
{
firstIntersectPointY = floorf(playerPosY / WALL_SIZE) * (WALL_SIZE)-1;
Notice you have -1
at the end instead of this.TILE_SIZE
which in your case should be WALL_SIZE