Съемные источники света, такие как Minecraft

Я преуспел в создании источников света, подобных тем, что были в Minecraft, и это дало очень хороший результат. Я использовал метод клеточных автоматов, чтобы создать следующий свет.

Но скажем, у меня есть 2 или более источников света рядом друг с другом, и я хочу удалить один из них.
Можете ли вы порекомендовать способ пересчета только затронутых плиток?

Вот изображение, показывающее один источник света. http://i.stack.imgur.com/E0dqR.png

Ниже мой код для расчета источника света и всех соседних плиток.

void World::processNeighborLight(Tile *pCurrent, int pLightLevel, int *pIterationCount)
{
*pIterationCount += 1; // Just to keep track of how many iterations were made.
pCurrent->updateLight(pLightLevel);
int newLight = pLightLevel - 1;
if (newLight <= 0) return;

Tile *N = pCurrent->getRelative(sf::Vector2i(0, -1));
Tile *E = pCurrent->getRelative(sf::Vector2i(1, 0));
Tile *S = pCurrent->getRelative(sf::Vector2i(0, 1));
Tile *W = pCurrent->getRelative(sf::Vector2i(-1, 0));

if (N->getLightLevel() < newLight)
{
N->updateLight(newLight);
processNeighborLight(N, newLight, pIterationCount);
}
if (E->getLightLevel() < newLight)
{
E->updateLight(newLight);
processNeighborLight(E, newLight, pIterationCount);
}
if (S->getLightLevel() < newLight)
{
S->updateLight(newLight);
processNeighborLight(S, newLight, pIterationCount);
}
if (W->getLightLevel() < newLight)
{
W->updateLight(newLight);
processNeighborLight(W, newLight, pIterationCount);
}
}

0

Решение

Вместо того, чтобы в каждой ячейке хранился уровень освещенности, можно вместо этого хранить коллекцию пар (источник света, уровень света) (дорого?), И аналогичным образом каждый источник света хранит коллекцию пар (ячейка, уровень света) (дешево! ).

void KillLight (LightSource & kill_me)
{
// All we really do is iterate through each illuminated cell, and remove this lightsource from
// their list of light sources
for (auto i = kill_me.cells.begin(); i != kill_me.cells.end(); ++i)
{
// The cell contains some kind of collection that contains either a list of lightsources that hit it or <lightsource, illumination level>
// pairs.  All we need to do is remove this light from that collection and recalculate the cell's light level

i->lights->erase (kill_me); // Note light sources must be comparable objects.

i->RecalculateMaxIllumination(); // The cell needs to figure out which of its sources is brightest now.
}

// And then handle other lightsource removal cleanup actions.  Probably just have this method be called by
// ~LightSource()
}

Если хранить в каждой ячейке список источников света, попадающих на нее, слишком дорого, то влияние того, что каждый источник света запоминает, какие ячейки он освещает, все еще остается дешевым. Я могу придумать альтернативные решения, но все они включают в себя какое-то отображение от данного источника света к набору всех ячеек, которые он освещает.

Это предполагает, конечно, что ваших источников света относительно мало по сравнению с количеством ячеек, и нет действительно сумасшедших источников света, которые освещают десятки тысяч ячеек.

0

Другие решения


По вопросам рекламы [email protected]