Fix ant physics: pickup, gravity, spawn angle, food drop

- Pickup checks cell ahead instead of current cell (ants walk in
  air and can't enter solid cells, so current cell was always air)
- Starting ants face randomly left/right instead of straight down
  into sand where they'd get stuck bouncing
- Gravity falls up to 4 cells/frame instead of 1 (was imperceptibly
  slow at worldSize=1024)
- tryDropFood checks cell below too so ants walking above home can
  still deposit food
This commit is contained in:
Jared Miller 2026-03-12 09:59:04 -04:00
parent 64d7bf6437
commit 328f8a76e2
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C

View file

@ -35,9 +35,9 @@ vec2 roundUvToCellCenter(vec2 uv) {
} }
bool tryDropFood(vec2 pos) { bool tryDropFood(vec2 pos) {
float materialId = texture(tWorld, roundUvToCellCenter(pos)).x; float currentMatId = texture(tWorld, roundUvToCellCenter(pos)).x;
float belowMatId = texture(tWorld, roundUvToCellCenter(pos - vec2(0., cellSize))).x;
return int(materialId) == MAT_HOME; return int(currentMatId) == MAT_HOME || int(belowMatId) == MAT_HOME;
} }
bool isObstacle(vec2 pos) { bool isObstacle(vec2 pos) {
@ -145,7 +145,7 @@ void main() {
} }
} }
pos = vec2(spawnX, surfaceY); pos = vec2(spawnX, surfaceY);
angle = -PI * 0.5; // face downward initially angle = (rand(vUv * 31337.) > 0.5) ? 0.0 : PI; // face randomly left or right
#else #else
pos = vec2(0.5); pos = vec2(0.5);
angle = rand(vUv * 10000.) * 2. * PI; angle = rand(vUv * 10000.) * 2. * PI;
@ -185,9 +185,14 @@ void main() {
bool isFalling = false; bool isFalling = false;
// GRAVITY: if nothing solid below and not at world bottom, fall // GRAVITY: if nothing solid below and not at world bottom, fall multiple cells
if (!belowSolid && pos.y > cellSize) { if (!belowSolid && pos.y > cellSize) {
for (int g = 0; g < 4; g++) {
if (pos.y <= cellSize) break;
float matBelow = texture(tWorld, roundUvToCellCenter(pos - vec2(0., cellSize))).x;
if (int(matBelow) != MAT_AIR) break;
pos.y -= cellSize; pos.y -= cellSize;
}
isFalling = true; isFalling = true;
} }
@ -326,23 +331,24 @@ void main() {
angle += PI * (noise - 0.5); angle += PI * (noise - 0.5);
} }
// ---- PICKUP ---- // ---- PICKUP (check cell ahead — ants walk in air, can't enter solid cells) ----
if (isCarrying == 0.) { if (isCarrying == 0.) {
float cellMatId = texture(tWorld, roundUvToCellCenter(pos)).x; vec2 aheadUv = roundUvToCellCenter(pos + vec2(cos(angle), sin(angle)) * cellSize);
int cellMatInt = int(cellMatId); float aheadMatId = texture(tWorld, aheadUv).x;
int aheadMatInt = int(aheadMatId);
if (cellMatInt == MAT_FOOD) { if (aheadMatInt == MAT_FOOD) {
isCarrying = 1.; isCarrying = 1.;
cargoMaterialId = cellMatId; cargoMaterialId = aheadMatId;
angle += PI; angle += PI;
storage = getMaxScentStorage(vUv); storage = getMaxScentStorage(vUv);
} else if (cellMatInt != MAT_AIR && cellMatInt != MAT_HOME) { } else if (aheadMatInt != MAT_AIR && aheadMatInt != MAT_HOME) {
vec4 props = texelFetch(uMaterialProps, ivec2(cellMatInt, 0), 0); vec4 props = texelFetch(uMaterialProps, ivec2(aheadMatInt, 0), 0);
float behavior = props.r; float behavior = props.r;
float hardness = props.b; float hardness = props.b;
if (behavior == BEHAVIOR_POWDER && hardness <= ANT_CARRY_STRENGTH) { if (behavior == BEHAVIOR_POWDER && hardness <= ANT_CARRY_STRENGTH) {
isCarrying = 1.; isCarrying = 1.;
cargoMaterialId = cellMatId; cargoMaterialId = aheadMatId;
angle += PI; angle += PI;
storage = getMaxScentStorage(vUv); storage = getMaxScentStorage(vUv);
} }