Я пытаюсь реализовать алгоритм генерации подземелья (presented here и demo-ed here), который включает в себя создание случайного числа ячеек, которые перекрывают друг друга. Затем клетки отталкиваются/разделяются и затем соединяются. Теперь первоначальный плакат/автор описал, что он использует Алгоритм разделения разделения, чтобы равномерно распределять ячейки по области. У меня не было большого опыта работы с алгоритмом флокирования и/или режимом управления разделением, поэтому я обратился к Google для объяснения (и нашел this). Моя реализация (на основе статьи последней упомянутой) заключается в следующем:Lua Separation Группы алгоритмов перекрытия перекрывают комнаты в один угол
function pdg:_computeSeparation(_agent)
local neighbours = 0
local rtWidth = #self._rooms
local v =
{
x = self._rooms[_agent].startX,
y = self._rooms[_agent].startY,
--velocity = 1,
}
for i = 1, rtWidth do
if _agent ~= i then
local distance = math.dist(self._rooms[_agent].startX,
self._rooms[_agent].startY,
self._rooms[i].startX,
self._rooms[i].startY)
if distance < 12 then
--print("Separating agent: ".._agent.." from agent: "..i.."")
v.x = (v.x + self._rooms[_agent].startX - self._rooms[i].startX) * distance
v.y = (v.y + self._rooms[_agent].startY - self._rooms[i].startY) * distance
neighbours = neighbours + 1
end
end
end
if neighbours == 0 then
return v
else
v.x = v.x/neighbours
v.y = v.y/neighbours
v.x = v.x * -1
v.y = v.y * -1
pdg:_normalize(v, 1)
return v
end
end
self._rooms представляет собой таблицу, которая содержит оригинальный X и Y позицию номер в сетке, вместе с его ширина и высота (EndX , endY).
Проблема заключается в том, что, вместо того, чтобы махонькие расположения клеток на сетке, он принимает перекрывающихся клетки и перемещает их в область, которая идет от 1,1 до расстояния + 2, расстояние + 2 (as seen in my video [youtube])
Я пытаюсь понять, почему это происходит.
В случае это необходимо, здесь я разобрать таблицу сетки, отдельные и заполнить клетки после разделения:
function pdg:separate()
if #self._rooms > 0 then
--print("NR ROOMS: "..#self._rooms.."")
-- reset the map to empty
for x = 1, self._pdgMapWidth do
for y = 1, self._pdgMapHeight do
self._pdgMap[x][y] = 4
end
end
-- now, we separate the rooms
local numRooms = #self._rooms
for i = 1, numRooms do
local v = pdg:_computeSeparation(i)
--we adjust the x and y positions of the items in the room table
self._rooms[i].startX = v.x
self._rooms[i].startY = v.y
--self._rooms[i].endX = v.x + self._rooms[i].endX
--self._rooms[i].endY = v.y + self._rooms[i].endY
end
-- we render them again
for i = 1, numRooms do
local px = math.abs(math.floor(self._rooms[i].startX))
local py = math.abs(math.floor(self._rooms[i].startY))
for k = self.rectMinWidth, self._rooms[i].endX do
for v = self.rectMinHeight, self._rooms[i].endY do
print("PX IS AT: "..px.." and k is: "..k.." and their sum is: "..px+k.."")
print("PY IS AT: "..py.." and v is: "..v.." and their sum is: "..py+v.."")
if k == self.rectMinWidth or
v == self.rectMinHeight or
k == self._rooms[i].endX or
v == self._rooms[i].endY then
self._pdgMap[px+k][py+v] = 1
else
self._pdgMap[px+k][py+v] = 2
end
end
end
end
end