I am trying to make a raycasting game. Everything is rendered correctly except when the ray is facing up (angle > PI) or facing right(angle > 0.5PI and < 1.5PI) lines are drawn on walls. I am not sure what is causing it to happen but I know that the lines are not affected by the rotation of the player only by the players position. I also tried rounding the rays position but that did not help.
Right and up ray walls.
The walls up close.
Left and down ray walls.
Code:
let rayX, rayY, rayAngle, rayDeltaX, rayDeltaY
for (let i = 0; i < this.screen.width; i ++) {
rayAngle = this.angle - this.fov / 2 + i * (this.fov / this.screen.width)
if (rayAngle < 0) {
rayAngle += Math.PI * 2
}
else if (rayAngle > Math.PI * 2) {
rayAngle -= Math.PI * 2
}
rayX = this.x
rayY = this.y
let stepY
if (rayAngle > Math.PI) {
stepY = -this.tileSize
rayY = Math.floor(rayY / this.tileSize) * this.tileSize - 1
}
else {
stepY = this.tileSize
rayY = Math.floor(rayY / this.tileSize) * this.tileSize + this.tileSize
}
rayX = this.x + (rayY - this.y) / Math.tan(rayAngle)
rayDeltaY = stepY
rayDeltaX = stepY / Math.tan(rayAngle)
while(true) {
if (this.Map.map[Math.floor(rayY / this.tileSize) * this.Map.width + Math.floor(rayX / this.tileSize)] == '#') {
break
}
rayX += rayDeltaX
rayY += rayDeltaY
}
let rayHorizontalX = rayX
let rayHorizontalY = rayY
let rayDistanceHorizontal = Math.sqrt((this.x - rayHorizontalX) ** 2 + (this.y - rayHorizontalY) ** 2)
rayX = this.x
rayY = this.y
let stepX
if (rayAngle > 0.5 * Math.PI && rayAngle < 1.5 * Math.PI) {
stepX = -this.tileSize
rayX = Math.floor(rayX / this.tileSize) * this.tileSize - 1
}
else {
stepX = this.tileSize
rayX = Math.floor(rayX / this.tileSize) * this.tileSize + this.tileSize
}
rayY = this.y + (rayX - this.x) * Math.tan(rayAngle)
rayDeltaY = stepX * Math.tan(rayAngle)
rayDeltaX = stepX
while(true) {
if (this.Map.map[Math.floor(rayY / this.tileSize) * this.Map.width + Math.floor(rayX / this.tileSize)] == '#') {
break
}
rayX += rayDeltaX
rayY += rayDeltaY
}
let rayVerticalX = rayX
let rayVerticalY = rayY
let rayDistanceVertical = Math.sqrt((this.x - rayVerticalX) ** 2 + (this.y - rayVerticalY) ** 2)
let rayFinalDistance
if (rayDistanceHorizontal < rayDistanceVertical) {
rayFinalDistance = rayDistanceHorizontal
ctx.fillStyle = 'darkblue'
}
else {
rayFinalDistance = rayDistanceVertical
ctx.fillStyle = 'blue'
}
let rayCorrectedDistance = rayFinalDistance * Math.cos(rayAngle - this.angle)
let lineHeight = this.tileSize * (this.screen.width / 2 / Math.tan(this.fov / 2)) / rayCorrectedDistance
let lineBottom = this.projectionPlane.centerY + lineHeight * 0.5
let lineTop = this.projectionPlane.height - lineBottom
ctx.fillRect(i, lineTop, 1, lineHeight)
}
Any help would be appreciated.