From 90f2879e9afb948fd106ce7813ea482cea63fb5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Sat, 10 Jul 2021 00:03:57 +0300 Subject: [PATCH] lua-test-202107100001 --- lua-test/main.lua | 140 +++++++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 75 deletions(-) diff --git a/lua-test/main.lua b/lua-test/main.lua index 544be06..d040b28 100644 --- a/lua-test/main.lua +++ b/lua-test/main.lua @@ -1,26 +1,19 @@ -local fov = 90 * math.pi / 180 - local playerx = 10 local playery = 10 -local angle = 0 +local angle = 1 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 +local sin = {0, 0.707, 1, 0.707, 0, -0.707, -1, -0.707} +local cos = {1, 0.707, 0, -0.707, -1, -0.707, 0, 0.707} function love.update(dt) - 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 + playerx = playerx + sin[angle] * playerspeed * dt + playerx = playerx + cos[angle] * playerswspeed * dt + playery = playery + cos[angle] * playerspeed * dt + playery = playery - sin[angle] * playerswspeed * dt end function love.keypressed(key) @@ -32,11 +25,13 @@ 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 + angle = angle + 1 + if angle > 8 then angle = 1 end + elseif key == 'e' then + angle = angle - 1 + if angle < 1 then angle = 8 end + elseif key == 'escape' then love.event.quit() end end @@ -59,13 +54,13 @@ function transform(wx, wy) 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 + local rx = cos[angle] * tx - sin[angle] * ty + local ry = cos[angle] * ty + 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 px = -rx / ry -- Screen space (scaling and translation) local hwidth = love.graphics.getWidth() / 2 @@ -82,88 +77,83 @@ function drawWall(wx1, wy1, wx2, wy2) local x2, z2 = transform(wx2, wy2) 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 clippingx = playerx + 0.001*sin[angle] + local clippingy = playery + 0.001*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 + if angle == 1 or angle == 5 then + y = clippingy + if wx1 == wx2 then x = wx1 + elseif (wx1 < wx2) == (wy1 < wy2) then x = wx1 - wy1 + y + else x = wx1 + wy1 - y + end + elseif angle == 3 or angle == 7 then + x = clippingx + if wy1 == wy2 then y = wy1 + elseif (wx1 < wx2) == (wy1 < wy2) then y = wy1 - wx1 + x + else y = wy1 + wx1 - x + end + elseif angle == 2 or angle == 6 then + if wy1 == wy2 then + x = clippingx + clippingy - wy1 + y = wy1 + elseif wx1 == wx2 then + x = wx1 + y = clippingx + clippingy - wx1 + else + x = (wx1 + clippingx + clippingy - wy1) / 2 + y = (wy1 + clippingy + clippingx - wx1) / 2 + end + elseif angle == 4 or angle == 8 then + if wy1 == wy2 then + x = clippingx - clippingy + wy1 + y = wy1 + elseif wx1 == wx2 then + x = wx1 + y = clippingy - clippingx + wx1 + else + x = (wx1 + clippingx - clippingy + wy1) / 2 + y = (wy1 + clippingy - clippingx + wx1) / 2 + end 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) + if z1 < 0 then x1, z1 = transform(x, y) + else x2, z2 = transform(x, y) end end - local wall1 = hwidth * 60 / z1 / math.tan(fov / 2) - local wall2 = hwidth * 60 / z2 / math.tan(fov / 2) + local wall1 = hwidth * 60 / z1 + local wall2 = hwidth * 60 / z2 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, -200, -200, 100) + drawWall(-300, -200, -100, 0) + drawWall(-100, 0, -300, 200) drawWall(-150, 200, 300, 200) drawWall(300, 200, 300, -200) drawWall(300, -200, -300, -200) - 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) + love.graphics.setColor(1, 1, 1) + anglecw = angle - 1 + if anglecw < 1 then anglecw = 8 end + anglecc = angle + 1 + if anglecc > 8 then anglecc = 1 end + love.graphics.line(hwidth, hheight, hwidth + sin[anglecw] * 5, hheight + cos[anglecw] * 5) + love.graphics.line(hwidth, hheight, hwidth + sin[anglecc] * 5, hheight + cos[anglecc] * 5) end