From 4c376f42d8813747e6689c5b2fa85325127ae068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Fri, 9 Jul 2021 21:44:23 +0300 Subject: [PATCH] lua-test-202107092059 --- lua-test/main.lua | 110 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 96 insertions(+), 14 deletions(-) diff --git a/lua-test/main.lua b/lua-test/main.lua index c590b02..544be06 100644 --- a/lua-test/main.lua +++ b/lua-test/main.lua @@ -1,3 +1,5 @@ +local fov = 90 * math.pi / 180 + local playerx = 10 local playery = 10 local angle = 0 @@ -6,9 +8,15 @@ local playerspeed = 0 local playerswspeed = 0 local playermaxspeed = 100 +function love.load() + love.mouse.setRelativeMode(true) +end + +function love.mousemoved(x, y, dx, dy) + angle = angle - dx / love.graphics.getWidth() * 2 * math.pi +end + 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 @@ -24,6 +32,12 @@ function love.keypressed(key) playerswspeed = playerswspeed + playermaxspeed elseif key == 'd' then playerswspeed = playerswspeed - playermaxspeed + elseif key == 'o' then + fov = fov + 10 * math.pi / 180 + elseif key == 'p' then + fov = fov - 10 * math.pi / 180 + elseif key == 'q' then + love.event.quit() end end @@ -39,8 +53,6 @@ function love.keyreleased(key) end end -local fov = 90 * math.pi / 180 - function transform(wx, wy) -- Player-relative space (translation) local tx = wx - playerx @@ -54,34 +66,104 @@ function transform(wx, wy) -- 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 + local z = ry - return x, pz + return x, z 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) + if z1 < 0 and z2 < 0 then + love.graphics.setColor(0.8, 0.7, 0.7) + love.graphics.line(wx1 + hwidth, wy1 + hheight, wx2 + hwidth, wy2 + hheight) + -- Fully outside of viewport, don't bother + return + end + + love.graphics.setColor(1, 0, 0) + love.graphics.line(wx1 + hwidth, wy1 + hheight, wx2 + hwidth, wy2 + hheight) + + if z1 < 0 or z2 < 0 then + local clippingx = playerx + 0.001*math.sin(angle) + local clippingy = playery + 0.001*math.cos(angle) + + local x = nil + local y = nil + + if wx2 ~= wx1 then + local clippingslope = -math.sin(angle)/math.cos(angle) + local wallslope = (wy2 - wy1)/(wx2 - wx1) + x = (-clippingslope*clippingx + clippingy + wallslope*wx1 - wy1)/(wallslope - clippingslope) + y = wallslope*(x - wx1) + wy1 + else + local perclippingslope = -math.cos(angle)/math.sin(angle) + local perwallslope = (wx2 - wx1)/(wy2 - wy1) + y = (-perclippingslope*clippingy + clippingx + perwallslope*wy1 - wx1)/(perwallslope - perclippingslope) + x = perwallslope*(y - wy1) + wx1 + end + + if z1 < 0 then + x1, z1 = transform(x, y) + love.graphics.setColor(0.8, 0.5, 0.5) + love.graphics.line(wx1 + hwidth, wy1 + hheight, x + hwidth, y + hheight) + else + x2, z2 = transform(x, y) + love.graphics.setColor(0.8, 0.5, 0.5) + love.graphics.line(x + hwidth, y + hheight, wx2 + hwidth, wy2 + hheight) + end + end + + local wall1 = hwidth * 60 / z1 / math.tan(fov / 2) + local wall2 = hwidth * 60 / z2 / math.tan(fov / 2) + + love.graphics.setColor(1, 1, 1) + love.graphics.line(x1, hheight - wall1, x2, hheight - wall2) + love.graphics.line(x1, hheight + wall1, x2, hheight + wall2) + love.graphics.line(x1, hheight - wall1, x1, hheight + wall1) + love.graphics.line(x2, hheight - wall2, x2, hheight + wall2) + + if z1 < 0 then + love.graphics.setColor(0, 0, 1) + square = { + wx1 - 5 + hwidth, wy1 - 5 + hheight, + wx1 + 5 + hwidth, wy1 - 5 + hheight, + wx1 + 5 + hwidth, wy1 + 5 + hheight, + wx1 - 5 + hwidth, wy1 + 5 + hheight, + } + love.graphics.polygon('fill', square) + love.graphics.line(hwidth+playerx, hheight+playery, hwidth+wx1, hheight+wy1) + end + if z2 < 0 then + love.graphics.setColor(0, 0, 1) + square = { + wx2 - 5 + hwidth, wy2 - 5 + hheight, + wx2 + 5 + hwidth, wy2 - 5 + hheight, + wx2 + 5 + hwidth, wy2 + 5 + hheight, + wx2 - 5 + hwidth, wy2 + 5 + hheight, + } + love.graphics.polygon('fill', square) + love.graphics.line(hwidth+playerx, hheight+playery, hwidth+wx2, hheight+wy2) + end end function love.draw() local hwidth = love.graphics.getWidth() / 2 local hheight = love.graphics.getHeight() / 2 - drawWall(-300, 100, 300, 100) + drawWall(-300, -200, -200, 100) + drawWall(-150, 200, 300, 200) + drawWall(300, 200, 300, -200) + drawWall(300, -200, -300, -200) - drawWall(playerx, playery, playerx + math.sin(angle) * 5, playery + math.cos(angle) * 5) + love.graphics.setColor(0, 1, 0) + love.graphics.line(hwidth+playerx, hheight+playery, hwidth+playerx + math.sin(angle + fov/2) * 5, hheight+playery + math.cos(angle + fov/2) * 5) + love.graphics.line(hwidth+playerx, hheight+playery, hwidth+playerx + math.sin(angle - fov/2) * 5, hheight+playery + math.cos(angle - fov/2) * 5) end