Rickton wrote:If the code's no help, I based the cave generator off of
this article, the "BSP Tree" off of
this article, and the maze off of
this, I think. The drunk walkers I made myself, so there's no article for that one.
Haha, for the heck of it I decided to start playing around with this using the Cellular Automata method link and after tweaking it a bit I came up with a pretty good algorithm so far...
Currently it generates the random map, then does the 5 step smoothing process. Then I added some post processing where it removes catty-corner empty spaces by replacing one of them with a wall for looks. It also checks for stray islands and removes most of them. And lastly marks certain tiles for potential door placement later.
I don't know what I'm doing with it though. But I have plans for later stuff. I want to use a fill algorithm to find all the individual sections of empty space, find all separate islands and depending on their size, either remove them or do something else with them, discard or integrate isolated parts whenever possible, and maybe later figure out how to make it a maze and add keys in proper places. (Find dead ends that are separated by a single narrow passageway/door and use them as special rooms.) As well as find large empty spaces and mark them as potential event rooms.
I dunno. No idea how I'd use it, but it's fun to experiment.
This is my generation code so far:
Code: Select all
function game:generateMap(w, h)
local startTime = love.timer.getTime()
local grid = self:generateGrid(w, h, true)
for x = 1, #grid-1 do
for y = 1, #grid[1]-1 do
grid[x][y] = math.random(0,100) < 32
end
end
self.oldGrids = {}
self.oldGrids[0] = grid
self.potentialDoors = {}
self.curLayer = 0
for i = 1, 5 do
local tempGrid = self:copyGrid(grid)
for x = 1, #grid-1 do
for y = 1, #grid[1]-1 do
local total = 0
for xx = x - 1, x + 1 do
for yy = y - 1, y + 1 do
if grid[xx][yy] then
total = total + 1
end
end
end
if total > 4 then
tempGrid[x][y] = true
end
end
end
grid = tempGrid
self.oldGrids[i] = grid
end
for x = 1, #grid-1 do
for y = 1, #grid[1]-1 do
local total = 0
if grid[x][y] then
for xx = x - 1, x + 1 do
for yy = y - 1, y + 1 do
if not grid[xx][yy] then
total = total + 1
end
end
end
end
if total >= 6 then
grid[x][y] = false
end
end
end
for x = 1, #grid-1 do
for y = 1, #grid[1]-1 do
if grid[x][y] and not grid[x+1][y] and not grid[x][y+1] and grid[x+1][y+1] then
local which = math.random(1,2)
if which == 1 then
grid[x+1][y] = true
else
grid[x][y+1] = true
end
end
if not grid[x][y] and grid[x+1][y] and grid[x][y+1] and not grid[x+1][y+1] then
local which = math.random(1,2)
if which == 1 then
grid[x][y] = true
else
grid[x+1][y+1] = true
end
end
end
end
for x = 1, #grid-1 do
for y = 1, #grid[1]-1 do
if not grid[x][y] and not grid[x-1][y] and not grid[x+1][y] and grid[x][y-1] and grid[x][y+1] then
self.potentialDoors[#self.potentialDoors+1] = {x = x, y = y, dir = "h"}
end
if not grid[x][y] and not grid[x][y-1] and not grid[x][y+1] and grid[x-1][y] and grid[x+1][y] then
self.potentialDoors[#self.potentialDoors+1] = {x = x, y = y, dir = "v"}
end
end
end
print("Time Taken:", love.timer.getTime() - startTime)
return grid
end
function game:generateGrid(w, h, pad)
local low = 1
local high = 0
if pad then low = 0 high = 1 end
local grid = {}
for x = low, w + high do
grid[x] = {}
for y = low, h + high do
grid[x][y] = true
end
end
return grid
end
function game:copyGrid(oldGrid)
local newGrid = {}
for x, gg in pairs(oldGrid) do
newGrid[x] = {}
for y, gg in pairs(oldGrid[x]) do
newGrid[x][y] = oldGrid[x][y]
end
end
return newGrid
end
In case it's useful to anyone. (You'll need to modify the code to make it work.)