246 lines
5.8 KiB
Lua
246 lines
5.8 KiB
Lua
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
|