像Minecraft这样的可拆卸光源

时间:2014-06-19 12:02:46

标签: c++ algorithm light

我已经成功制作了类似Minecraft中的光源,并且它获得了非常好的结果。我已经使用细胞自动机方法来创建以下光。

但是说我有两个或更多的光源彼此靠近,我想删除其中一个。 你能推荐一种只重新计算受影响的瓷砖的方法吗?

这是显示一个光源的图像。 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);
    }
}

1 个答案:

答案 0 :(得分: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()
}

如果让每个细胞存储光源列表太昂贵,那么让每个光源记住它所照射的细胞的影响仍然很便宜。我可以想到其他解决方案,但它们都涉及从给定光源到它所照亮的所有单元的集合的某种映射。

当然,这假设您的光源数量与细胞数量相比相对较少,并且没有真正疯狂的发光光源照亮数万个细胞。