local playerx = 10 local playery = 10 local angle = 0 local playerspeed = 0 local playerswspeed = 0 local playermaxspeed = 100 function love.update(dt) local mousex, mousey = love.mouse.getPosition() angle = -(mousex / love.graphics.getWidth()) + 0.5 playerx = playerx + math.sin(angle) * playerspeed * dt playerx = playerx + math.cos(angle) * playerswspeed * dt playery = playery + math.cos(angle) * playerspeed * dt playery = playery - math.sin(angle) * playerswspeed * dt end function love.keypressed(key) if key == 'w' then playerspeed = playerspeed + playermaxspeed elseif key == 's' then playerspeed = playerspeed - playermaxspeed elseif key == 'a' then playerswspeed = playerswspeed + playermaxspeed elseif key == 'd' then playerswspeed = playerswspeed - playermaxspeed end end function love.keyreleased(key) if key == 'w' then playerspeed = playerspeed - playermaxspeed elseif key == 's' then playerspeed = playerspeed + playermaxspeed elseif key == 'a' then playerswspeed = playerswspeed - playermaxspeed elseif key == 'd' then playerswspeed = playerswspeed + playermaxspeed end end local fov = 90 * math.pi / 180 function transform(wx, wy) -- Player-relative space (translation) local tx = wx - playerx local ty = wy - playery -- Player-relative space (rotation) local rx = math.cos(angle) * tx - math.sin(angle) * ty local ry = math.cos(angle) * ty + math.sin(angle) * tx -- -1.0 to +1.0 abstract screen space (perspective) -- Player-relative x maps to *-x* -- Player-relative y maps to *z* local px = -rx / ry / math.tan(fov / 2) local pz = ry -- Screen space (scaling and translation) local hwidth = love.graphics.getWidth() / 2 local x = px * hwidth + hwidth return x, pz end function drawWall(wx1, wy1, wx2, wy2) local hwidth = love.graphics.getWidth() / 2 local hheight = love.graphics.getHeight() / 2 love.graphics.setColor(255, 0, 0) love.graphics.line(wx1 + hwidth, wy1 + hheight, wx2 + hwidth, wy2 + hheight) local x1, z1 = transform(wx1, wy1) local x2, z2 = transform(wx2, wy2) love.graphics.setColor(255, 255, 255) love.graphics.line(x1, hheight - 60 * hheight / z1 / math.tan(fov / 2), x2, hheight - 60 * hheight / z2 / math.tan(fov / 2)) love.graphics.line(x1, hheight + 60 * hheight / z1, x2, hheight + 60 * hheight / z2) end function love.draw() local hwidth = love.graphics.getWidth() / 2 local hheight = love.graphics.getHeight() / 2 drawWall(-300, 100, 300, 100) drawWall(playerx, playery, playerx + math.sin(angle) * 5, playery + math.cos(angle) * 5) end