像《我的世界》这样的可移动光源

Removeable lightsources like Minecraft

本文关键字:我的世界 可移动 光源      更新时间:2023-10-16

我已经成功地制作了像《我的世界》中的光源,它带来了一个非常好的结果。我使用元胞自动机方法创建了下面的光。

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

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

你可以,而不是让每个单元存储一个光电平,让它存储(光源,光电平)对的集合(昂贵?),类似地,每个光源存储(细胞,光电平)对的集合(便宜!)。

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()
}

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

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