From 36f0188f0f02a52d0c239a613f97be6decfb8577 Mon Sep 17 00:00:00 2001 From: Matthew Ryan Dillon Date: Sat, 28 Dec 2024 21:59:15 -0500 Subject: [PATCH] initial --- main.lua | 246 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 main.lua diff --git a/main.lua b/main.lua new file mode 100644 index 0000000..4dee6ac --- /dev/null +++ b/main.lua @@ -0,0 +1,246 @@ +function love.load() + p2 = math.pi / 2 + p3 = 3 * math.pi / 2 + + fov = 30 + + love.graphics.setBackgroundColor(0.3, 0.3, 0.3, 1) + love.window.setMode(1024, 512) + + player = {} + player["x"] = 300 + player["y"] = 300 + player["size"] = 8 + player["angle"] = 0 + player["dx"] = math.cos(player.angle) * 5 + player["dy"] = math.sin(player.angle) * 5 + + map = {} + map["x"] = 8 + map["y"] = 8 + map["size"] = 64 + + map["map"] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 0, 0, 0, 1, + 1, 0, 1, 0, 0, 0, 0, 1, + 1, 0, 1, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 0, 0, 0, 1, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + } +end + +function love.update() + if love.keyboard.isDown("a") then + player.angle = player.angle - 0.1 + if player.angle < 0 then player.angle = player.angle + 2 * math.pi end + player.dx = math.cos(player.angle) * 5 + player.dy = math.sin(player.angle) * 5 + end + if love.keyboard.isDown("d") then + player.angle = player.angle + 0.1 + if player.angle > 2 * math.pi then player.angle = player.angle - 2 * math.pi end + player.dx = math.cos(player.angle) * 5 + player.dy = math.sin(player.angle) * 5 + end + if love.keyboard.isDown("w") then + player.x = player.x + player.dx + player.y = player.y + player.dy + end + if love.keyboard.isDown("s") then + player.x = player.x - player.dx + player.y = player.y - player.dy + end +end + +function love.draw() + drawMap() + drawPlayer() + drawRays3D() +end + +function drawPlayer() + love.graphics.setColor(1, 1, 0) + love.graphics.rectangle("fill", + player.x - player.size / 2, player.y - player.size / 2, + player.size, player.size + ) + love.graphics.line(player.x, player.y, player.x + player.dx * 5, player.y + player.dy * 5) +end + +function drawMap() + for y = 1, map.y do + for x = 1, map.x do + local color = map.map[(y - 1) * map.x + x] + love.graphics.setColor(color, color, color) + local xo = (x - 1) * map.size + local yo = (y - 1) * map.size + love.graphics.polygon("fill", + xo + 1, yo + 1, + xo + 1, yo + map.size - 1, + xo + map.size - 1, yo + map.size - 1, + xo + map.size - 1, yo + 1 + ) + end + end +end + +function dist(ax, ay, bx, by, ang) + return math.sqrt((bx - ax) * (bx - ax) + (by - ay) * (by - ay)) +end + +function drawRays3D() + local ray = {} + ray["angle"] = player.angle - math.rad(fov) + ray["x"] = 0 + ray["y"] = 0 + ray["xo"] = 0 + ray["yo"] = 0 + ray["mx"] = 0 + ray["my"] = 0 + ray["mp"] = 0 + + if ray.angle < 0 then + ray.angle = ray.angle + 2 * math.pi + end + if ray.angle > 2 * math.pi then + ray.angle = ray.angle - 2 * math.pi + end + + for r = 1, fov * 2 do + local dof = 0 + local disT = 0 + local disH = 1000000 + local hx = player.x + local hy = player.y + + local aTan = -1 / math.tan(ray.angle) + + if (ray.angle > math.pi) then + ray.y = bit.lshift(bit.rshift(player.y, 6), 6) - 0.0001 + ray.x = (player.y - ray.y) * aTan + player.x + ray.yo = -map.size + ray.xo = -ray.yo * aTan + end + + if (ray.angle < math.pi) then + ray.y = bit.lshift(bit.rshift(player.y, 6), 6) + map.size + ray.x = (player.y - ray.y) * aTan + player.x + ray.yo = map.size + ray.xo = -ray.yo * aTan + end + + if ray.angle == 0 or ray.angle == math.pi then + ray.x = player.x + ray.y = player.y + dof = 8 + end + + while dof < 8 do + ray.mx = bit.rshift(ray.x, 6) + ray.my = bit.rshift(ray.y, 6) + ray.mp = ray.my * map.x + ray.mx + if ray.mp > 0 and ray.mp < (map.x * map.y + 1) and map.map[ray.mp + 1] == 1 then + hx = ray.x + hy = ray.y + disH = dist(player.x, player.y, hx, hy, ray.angle) + dof = 8 + else + ray.x = ray.x + ray.xo + ray.y = ray.y + ray.yo + dof = dof + 1 + end + end + + dof = 0 + local disV = 1000000 + local vx = player.x + local vy = player.y + local nTan = -math.tan(ray.angle) + + if (ray.angle > p2 and ray.angle < p3) then + ray.x = bit.lshift(bit.rshift(player.x, 6), 6) - 0.0001 + ray.y = (player.x - ray.x) * nTan + player.y + ray.xo = -map.size + ray.yo = -ray.xo * nTan + end + + if (ray.angle < p2 or ray.angle > p3) then + ray.x = bit.lshift(bit.rshift(player.x, 6), 6) + map.size + ray.y = (player.x - ray.x) * nTan + player.y + ray.xo = map.size + ray.yo = -ray.xo * nTan + end + + if ray.angle == 0 or ray.angle == math.pi then + ray.x = player.x + ray.y = player.y + dof = 8 + end + + while dof < 8 do + ray.mx = bit.rshift(ray.x, 6) + ray.my = bit.rshift(ray.y, 6) + ray.mp = ray.my * map.x + ray.mx + if ray.mp > 0 and ray.mp < (map.x * map.y + 1) and map.map[ray.mp + 1] == 1 then + vx = ray.x + vy = ray.y + disV = dist(player.x, player.y, vx, vy, ray.angle) + dof = 8 + else + ray.x = ray.x + ray.xo + ray.y = ray.y + ray.yo + dof = dof + 1 + end + end + + if disV < disH then + ray.x = vx + ray.y = vy + disT = disV + love.graphics.setColor(0.9, 0, 0) + end + + if disH < disV then + ray.x = hx + ray.y = hy + disT = disH + love.graphics.setColor(0.7, 0, 0) + end + + love.graphics.line( + player.x, player.y, + ray.x, ray.y + ) + + local ca = player.angle - ray.angle + if ca < 0 then + ca = ca + 2 * math.pi + end + if ca > 2 * math.pi then + ca = ca - 2 * math.pi + end + disT = disT * math.cos(ca) + + local lineH = map.size * 320 / disT + if lineH > 320 then + lineH = 320 + end + local lineO = 160 - lineH / 2 + love.graphics.setLineWidth(8) + love.graphics.line( + r * 8 + 530, lineO, + r * 8 + 530, lineH + lineO + ) + + ray.angle = ray.angle + math.rad(1) + if ray.angle < 0 then + ray.angle = ray.angle + 2 * math.pi + end + if ray.angle > 2 * math.pi then + ray.angle = ray.angle - 2 * math.pi + end + end +end