简述
这是一种模拟粒子移动以及粒子交互的方式,在游戏 Noita 中使用了此方式来模拟沙子及其它粒子,在这儿可以找到在线示例。
开始
此模拟方式的本质是一个元胞自动机,每个粒子按照特定规则更新。
在此示例中,演示了在 2D 空间中的模拟情况。在此将世界视为一个二维网格,每个网格都可以包含一个粒子,可以使用二维矩阵来表示它。
可以使用如下结构体来表示粒子:
struct Particle {
uint8_t type;
uint8_t density;
vec2 velocity;
bool isLiquids;
bool updated;
...
}
为了实现过程,需要遍历网格并更新:
for (int y = 0; y < elements.height; y++) {
for (int x = 0; x < elements.width; x++) {
Particle p = & elements[x][y];
if (p.updated) continue;
if (p.type == 0) continue;
if (p.type == TYPE_SAND) emulateSand(x, y);
...
}
}
粒子
沙子:规则
- 如果一个沙子的下方为空,则将其向下移动
- 如果下方不为空,则尝试向左下或右下移动
- 如果正下方及侧下方不为空,则保持位置
水:规则
优化
在每次更新中迭代整个网格性能较低,为了解决此问题,可将世界分成若干小块,并根据需要激活/更新更新块