123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- Grid = class()
- function Grid:init()
- for y = 1, HEIGHT do
- self[y] = {}
- end
- end
- function Grid:set(x, y, c, char, room)
- if not room then
- room = self[y][x].room
- end
- self[y][x] = c(x, y, char, room)
- end
- function Grid:update(world, key)
- for y = 1, HEIGHT do
- for x = 1, WIDTH do
- self[y][x]:update(world)
- end
- end
- end
- function Grid:draw(text)
- for y = 1, HEIGHT do
- for x = 1, WIDTH do
- if self[y][x].lit then
- text[y][x] = self[y][x]
- end
- end
- end
- end
- -- draws
- function Grid:room(r)
- local room = {}
- a, b = r[1], r[2]
- for y = a.y + 1, b.y - 1 do
- for x = a.x + 1, b.x - 1 do
- self:set(x, y, Air, '.', room)
- room[#room + 1] = {x = x, y = y}
- end
- end
- for y = a.y, b.y do
- for x = a.x, b.x do
- if not self[y][x] then
- self:set(x, y, Wall, '#', {})
- end
- end
- end
- end
- function rectIntersects(a, b)
- return a[1].x <= b[2].x and b[1].x <= a[2].x and a[1].y <= b[2].y and b[1].y <= a[2].y
- end
- function roomAround(v)
- return {
- {
- x = math.max(1, v.x - love.math.random(3, 6)),
- y = math.max(1, v.y - love.math.random(3, 6))
- },
- {
- x = math.min(WIDTH - 1, v.x + love.math.random(3, 6)),
- y = math.min(HEIGHT - 1, v.y + love.math.random(3, 6))
- }
- }
- end
- function randomRoom()
- return roomAround(randomPoint())
- end
- function Grid:emptySpace()
- for y = 1, HEIGHT do
- for x = 1, WIDTH do
- if not self[y][x] then
- self[y][x] = Wall(x, y, ' ', {})
- end
- end
- end
- end
- function Grid:lightAll()
- for y = 1, HEIGHT do
- for x = 1, WIDTH do
- self[y][x].lit = true
- end
- end
- end
- -- straight line (has to be along a direct cardinal or whatever you call it)
- function Grid:line(a, b)
- local x, y = a.x, a.y
- local vx, vy = 0, 0
- local out = {a}
- if b.x > a.x then
- vx = 1
- elseif b.x < a.x then
- vx = -1
- end
- if b.y > a.y then
- vy = 1
- elseif b.y < a.y then
- vy = -1
- end
- while x ~= b.x or y ~= b.y do
- x = x + vx
- y = y + vy
- out[#out + 1] = {x = x, y = y}
- end
- return out
- end
- function Grid:lineAir(a, b)
- l = self:line(a, b)
- for _, v in pairs(l) do
- self:set(v.x, v.y, Air, '.', {})
- end
- end
- -- random, maze-y path to an area
- function Grid:path(a, b)
- local v = cloneVec(a) -- Lua pls
- local vx, vy = 0, 0
- local out = {}
- if b.x > a.x then
- vx = 1
- elseif b.x < a.x then
- vx = -1
- end
- if b.y > a.y then
- vy = 1
- elseif b.y < a.y then
- vy = -1
- end
- while v.x ~= b.x or v.y ~= b.y do
- local line
- if love.math.random(1, 2) == 1 and b.x ~= v.x then
- local amount = math.min(love.math.random(5), math.abs(b.x - v.x))
- line = self:line(v, {x = v.x + math.max(0, amount - 1) * vx, y = v.y})
- v.x = v.x + amount * vx
- else
- local amount = math.min(love.math.random(5), math.abs(b.y - v.y))
- line = self:line(v, {y = v.y + math.max(0, amount - 1) * vy, x = v.x})
- v.y = v.y + amount * vy
- end
- for _, v in pairs(line) do
- out[#out + 1] = cloneVec(v)
- end
- end
- out[#out + 1] = cloneVec(v)
- return out
- end
- function Grid:pathAir(a, b)
- l = self:path(a, b)
- for _, v in pairs(l) do
- self:set(v.x, v.y, Air, '.', {})
- end
- end
- function randomInRoom(r)
- return {
- x = love.math.random(r[1].x + 1, r[2].x - 1),
- y = love.math.random(r[1].y + 1, r[2].y - 1)
- }
- end
- function randomPoint()
- return {
- x = love.math.random(1, WIDTH - 1),
- y = love.math.random(1, HEIGHT - 1)
- }
- end
- function Grid:generateLevel(start)
- local rooms = {roomAround(start)}
- for i = 1, love.math.random(5, 10) do
- local newRoom
- local collide = true
- while collide do
- newRoom = randomRoom()
- collide = false
- for _, r in pairs(rooms) do
- if rectIntersects(newRoom, r) then
- collide = true
- end
- end
- end
- local oldRoom = rooms[love.math.random(#rooms)]
- self:pathAir(randomInRoom(oldRoom), randomInRoom(newRoom))
- rooms[#rooms + 1] = newRoom
- end
- for _, r in pairs(rooms) do
- self:room(r)
- end
- for i = 1, self.level == 1 and 6 or love.math.random(1, 3) do
- p = randomInRoom(rooms[love.math.random(2, #rooms)])
- self:set(p.x, p.y, Stair, '>')
- end
- for i = 1, self.level == 1 and 6 or love.math.random(1, 6) do
- p = randomInRoom(rooms[love.math.random(1, #rooms)])
- self:set(p.x, p.y, Chest, 'C')
- end
- self:emptySpace()
- end
|