fix: correct dirt autotile direction and simplify edge logic
Dirt tiles (dirt-on-transparent) must be applied to DIRT tiles checking for non-dirt neighbors, not to GRASS tiles. The previous approach had dirt edges facing the wrong direction because the dirt island's edges point inward from the center, not outward from the grass. Water edges (watergrass = grass-on-water) remain applied to GRASS tiles since the grass portion aligns correctly with the base grass layer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -163,34 +163,59 @@ export class GameScene extends Phaser.Scene {
|
||||
return terrain[y * worldWidth + x];
|
||||
};
|
||||
|
||||
// For a GRASS tile, pick the watergrass/dirt transition tile based on
|
||||
// which neighbors are the "other" terrain type.
|
||||
// The LPC edge tiles are drawn FROM the grass perspective (grass is the terrain,
|
||||
// water/dirt is the background bleeding through at edges).
|
||||
const pickEdgeTile = (x: number, y: number, otherTerrain: number): number => {
|
||||
const isOther = (dx: number, dy: number) => getTerr(x + dx, y + dy) === otherTerrain;
|
||||
const n = isOther(0, -1), s = isOther(0, 1), w = isOther(-1, 0), e = isOther(1, 0);
|
||||
const nw = isOther(-1, -1), ne = isOther(1, -1), sw = isOther(-1, 1), se = isOther(1, 1);
|
||||
// Pick autotile for a GRASS tile in the watergrass layer.
|
||||
// watergrass.png = grass-on-water: edge tiles show grass with water bleeding through.
|
||||
// Applied to GRASS tiles, checking which neighbors are WATER.
|
||||
const pickWaterEdge = (x: number, y: number): number => {
|
||||
const isW = (dx: number, dy: number) => getTerr(x + dx, y + dy) === Terrain.WATER;
|
||||
const n = isW(0, -1), s = isW(0, 1), w = isW(-1, 0), e = isW(1, 0);
|
||||
const nw = isW(-1, -1), ne = isW(1, -1), sw = isW(-1, 1), se = isW(1, 1);
|
||||
|
||||
// Outer corners (two cardinal sides are the other terrain)
|
||||
if (n && w) return 6; // outer-NW: grass only in SE, other terrain in NW
|
||||
if (n && e) return 8; // outer-NE
|
||||
if (s && w) return 12; // outer-SW
|
||||
if (s && e) return 14; // outer-SE
|
||||
// Edges (one cardinal side is the other terrain)
|
||||
if (n) return 7; // N-edge: other terrain bleeds from north
|
||||
if (s) return 13; // S-edge
|
||||
if (w) return 9; // W-edge
|
||||
if (e) return 11; // E-edge
|
||||
// Inner corners (all cardinal = grass, but a diagonal is the other terrain)
|
||||
if (se) return 0; // inner-SE: other terrain peeks in SE corner
|
||||
if (sw) return 1; // inner-SW
|
||||
if (ne) return 3; // inner-NE
|
||||
if (nw) return 4; // inner-NW
|
||||
// No adjacent other-terrain at all
|
||||
// Outer corners (two cardinal sides are water)
|
||||
if (n && w) return 6;
|
||||
if (n && e) return 8;
|
||||
if (s && w) return 12;
|
||||
if (s && e) return 14;
|
||||
// Edges (one cardinal side is water)
|
||||
if (n) return 7;
|
||||
if (s) return 13;
|
||||
if (w) return 9;
|
||||
if (e) return 11;
|
||||
// Inner corners (diagonal-only water) — small water notch in grass
|
||||
if (se) return 0;
|
||||
if (sw) return 1;
|
||||
if (ne) return 3;
|
||||
if (nw) return 4;
|
||||
return -1;
|
||||
};
|
||||
|
||||
// Pick autotile for a DIRT tile in the dirt layer.
|
||||
// dirt.png = dirt-on-transparent: edge tiles show dirt with transparent edges.
|
||||
// Applied to DIRT tiles, checking which neighbors are NOT dirt.
|
||||
const pickDirtEdge = (x: number, y: number): number => {
|
||||
const notDirt = (dx: number, dy: number) => getTerr(x + dx, y + dy) !== Terrain.DIRT;
|
||||
const n = notDirt(0, -1), s = notDirt(0, 1), w = notDirt(-1, 0), e = notDirt(1, 0);
|
||||
const nw = notDirt(-1, -1), ne = notDirt(1, -1), sw = notDirt(-1, 1), se = notDirt(1, 1);
|
||||
|
||||
// Outer corners (two sides are not-dirt → this dirt tile is at a corner of the dirt body)
|
||||
if (n && w) return 6;
|
||||
if (n && e) return 8;
|
||||
if (s && w) return 12;
|
||||
if (s && e) return 14;
|
||||
// Edges
|
||||
if (n) return 7;
|
||||
if (s) return 13;
|
||||
if (w) return 9;
|
||||
if (e) return 11;
|
||||
// Inner corners (diagonal-only grass → small transparent notch in dirt)
|
||||
if (se) return 0;
|
||||
if (sw) return 1;
|
||||
if (ne) return 3;
|
||||
if (nw) return 4;
|
||||
// Fully surrounded by dirt
|
||||
return FILL;
|
||||
};
|
||||
|
||||
// Build tile data arrays for each layer
|
||||
const grassData: number[][] = []; // base: solid grass everywhere
|
||||
const waterData: number[][] = []; // watergrass transitions + solid water
|
||||
@@ -209,20 +234,18 @@ export class GameScene extends Phaser.Scene {
|
||||
// Base: always solid grass
|
||||
grassRow.push(FILL);
|
||||
|
||||
// Water layer
|
||||
// Water layer: watergrass edges on GRASS tiles, solid fill on WATER tiles
|
||||
if (t === Terrain.WATER) {
|
||||
waterRow.push(FILL); // solid water
|
||||
waterRow.push(FILL);
|
||||
} else if (t === Terrain.GRASS) {
|
||||
waterRow.push(pickEdgeTile(x, y, Terrain.WATER));
|
||||
waterRow.push(pickWaterEdge(x, y));
|
||||
} else {
|
||||
waterRow.push(-1);
|
||||
}
|
||||
|
||||
// Dirt layer
|
||||
// Dirt layer: dirt edges on DIRT tiles (checking for non-dirt neighbors)
|
||||
if (t === Terrain.DIRT) {
|
||||
dirtRow.push(FILL); // solid dirt
|
||||
} else if (t === Terrain.GRASS) {
|
||||
dirtRow.push(pickEdgeTile(x, y, Terrain.DIRT));
|
||||
dirtRow.push(pickDirtEdge(x, y));
|
||||
} else {
|
||||
dirtRow.push(-1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user