viewtopic.php?f=4&t=6834&start=10#p45793
----Original post starts here----
I would really love to see a working Raycasting example that worked in Löve. I've tried converting numerous JavaScript versions with no luck at all. It's always just out of reach. Surely it can't be hard.
There was an example in the "What are you working on" thread a while ago but it was a bit buggy. I just tried the code now and it just looks and works wrong. I'm not talking about the fisheye, rather some other glitches. This is the code that was posted there:
Code: Select all
-------------------------------------------------------------------
--Raycasting sample code (written by Roland Yonaba)
-- Credits to :http://lodev.org/cgtutor/raycasting.html
-------------------------------------------------------------------
local map = {
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1},
{1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1},
{1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
}
local map_height,map_width = #map,#map[1]
local posX,posY = 22,12
local dirX,dirY = -1,0
local planeX,planeY = 0,0.66
local time,oldtime = 0,0
local w = love.graphics.getWidth()
local h = love.graphics.getHeight()
local moveSpeed, rotSpeed = 0,0
function love.update(dt)
moveSpeed = dt*3
rotSpeed = dt
if love.keyboard.isDown('up') then
if map[math.floor(posX+dirX*moveSpeed)][math.floor(posY)] == 0 then
posX = posX + dirX*moveSpeed
end
if map[math.floor(posX)][math.floor(posY+dirY*moveSpeed)] == 0 then
posY = posY + dirY*moveSpeed
end
end
if love.keyboard.isDown('down') then
if map[math.floor(posX-dirX*moveSpeed)][math.floor(posY)] == 0 then
posX = posX - dirX*moveSpeed
end
if map[math.floor(posX)][math.floor(posY-dirY*moveSpeed)] == 0 then
posY = posY - dirY*moveSpeed
end
end
if love.keyboard.isDown('left') then
local oldDirX = dirX
dirX = dirX * math.cos(rotSpeed)- dirY*math.sin(rotSpeed)
dirY = oldDirX * math.sin(rotSpeed)+ dirY*math.cos(rotSpeed)
local oldPlaneX = planeX
planeX = planeX * math.cos(rotSpeed) - planeY*math.sin(rotSpeed)
planeY = oldPlaneX * math.sin(rotSpeed) + planeY*math.cos(rotSpeed)
end
if love.keyboard.isDown('right') then
local oldDirX = dirX
dirX = dirX * math.cos(-rotSpeed)- dirY*math.sin(-rotSpeed)
dirY = oldDirX * math.sin(-rotSpeed)+ dirY*math.cos(-rotSpeed)
local oldPlaneX = planeX
planeX = planeX * math.cos(-rotSpeed) - planeY*math.sin(-rotSpeed)
planeY = oldPlaneX * math.sin(-rotSpeed) + planeY*math.cos(-rotSpeed)
end
end
function love.draw()
love.graphics.clear({0,0,0})
for x = 0,w do
local camX = 2*(x/w)-1
local rayPosX = posX
local rayPosY = posY
local rayDirX = dirX + planeX*camX
local rayDirY = dirY + planeY*camX
local mapX = math.floor(rayPosX)
local mapY = math.floor(rayPosY)
local sideDistX,sideDistY
local deltaDistX = math.sqrt(1+(rayDirY^2)/(rayDirX^2))
local deltaDistY = math.sqrt(1+(rayDirX^2)/(rayDirY^2))
local perpWallDist
local stepX,stepY
local hit = 0
local side
if rayDirX<0 then
stepX = -1
sideDistX = (rayPosX - mapX)*deltaDistX
else
stepX = 1
sideDistX = (mapX+1-rayPosX)*deltaDistX
end
if rayDirY <0 then
stepY = -1
sideDistY = (rayPosY - mapY) * deltaDistY
else
stepY = 1
sideDistY = (rayPosY +1-rayPosY)*deltaDistY
end
while (hit==0) do
if (sideDistX < sideDistY) then
sideDistX = sideDistX + deltaDistX
mapX = mapX+stepX
side = 0
else
sideDistY = sideDistY + deltaDistY
mapY = mapY + stepY
side = 1
end
if map[mapX][mapY] > 0 then hit = 1 end
end
if side==0 then
perpWallDist = math.abs((mapX - rayPosX+(1-stepX)/2)/rayDirX)
else
perpWallDist = math.abs((mapY - rayPosY+(1-stepY)/2)/rayDirY)
end
local lineHeight = math.abs(math.floor(h/perpWallDist))
local drawStart = -lineHeight/2 + h/2
if drawStart < 0 then drawStart = 0 end
local drawEnd = lineHeight/2 + h/2
if drawEnd >= h then drawEnd = h-1 end
local color = {}
local square = map[mapX][mapY]
if square == 1 then color = {255,0,0}
elseif square == 2 then color = {0,255,0}
elseif square == 3 then color = {0,0,255}
elseif square == 4 then color = {255,255,255}
else color = {255,255,0}
end
if side == 1 then
for k,v in ipairs(color) do v = v/2 end
end
love.graphics.setColor(color)
love.graphics.line(x,drawStart,x,drawEnd)
end
end
Surely if it could be done so perfectly in 1992, it can be done right now. I'm not even concerned about image textures yet. I just want the shapes. The textures would come later based on where along the wall tile a ray is touching and dividing the texture into a quad per horizontal pixel unit. Blah blah blah.