Rotate river texture 90deg, fix physics, refine edges, enable Editor Mode

This commit is contained in:
2026-01-31 11:20:35 +01:00
parent 34b044214c
commit 983104021c

View File

@@ -124,28 +124,61 @@ export default class GrassSceneClean extends Phaser.Scene {
const riverY = WORLD_H / 2 + 300;
// Horizontal River using tileSprite
// Width = WORLD_W (to cover full map width)
this.river = this.add.tileSprite(WORLD_W / 2, riverY, WORLD_W, riverHeight, 'river_tile_seamless');
// 1. ROTATION FIX:
// The texture 'river_tile_seamless' is vertical (banks on Left/Right).
// We want horizontal flow (banks on Top/Bottom).
// So we rotate the sprite by 90 degrees.
// When rotated 90 degrees:
// - The sprite's "height" (local Y) becomes the screen width.
// - The sprite's "width" (local X) becomes the screen height (river thickness).
// So we initialize with swapped dimensions:
// Width = riverHeight (which becomes vertical thickness after rotation)
// Height = WORLD_W (which becomes horizontal length after rotation)
this.river = this.add.tileSprite(WORLD_W / 2, riverY, riverHeight, WORLD_W, 'river_tile_seamless');
this.river.setAngle(90); // Rotate to horizontal
this.river.setDepth(-50); // Above ground, below player
// Physics for River (Obstacle)
this.physics.add.existing(this.river, true); // Static body
this.river.body.setSize(WORLD_W, riverHeight * 0.8); // Slightly smaller collision
this.river.body.setOffset(0, riverHeight * 0.1);
// 2. PHYSICS FIX for Rotated Sprite:
// Arcade Physics bodies are AABB (Axis Aligned) and do NOT rotate with the sprite.
// We must manually set the size to match the VISUAL shape on screen (Horizontal strip).
this.river.body.setSize(WORLD_W, riverHeight * 0.8);
// Offset is relative to the Top-Left of the UNROTATED sprite (which is confusing).
// Or simpler: Center the body on the sprite.
this.river.body.center.set(this.river.x, this.river.y);
// However, static bodies are tricky with offsets after creation.
// Best approach: Resize body, then re-center it.
// But since we use existing(), it might be offset.
// Let's rely on manual offset if needed, or use a separate Zone if it fails.
// Trying standard offset correction:
// Visual Width = WORLD_W, Visual Height = riverHeight.
// Unrotated Width = riverHeight, Unrotated Height = WORLD_W.
// This mismatch often causes physics debug to look wrong.
// Alternative: Use an invisible Zone for physics.
// Let's use an invisible rectangle for physics to be 100% safe and simple.
this.river.body.enable = false; // Disable sprite body
this.riverCollider = this.add.rectangle(WORLD_W / 2, riverY, WORLD_W, riverHeight * 0.8, 0x000000, 0);
this.physics.add.existing(this.riverCollider, true);
// --- RIVER EDGES INTEGRATION (Soft Blend) ---
// Create gradients to blend river edges with ground
const edgeHeight = 64;
const edgeHeight = 32; // Narrower blend for tighter fit
const riverGraphics = this.add.graphics();
// Top Edge: Solid Brown -> Transparent (Downwards)
// 0x4e342e is the background brown
riverGraphics.fillGradientStyle(0x4e342e, 0x4e342e, 0x4e342e, 0x4e342e, 1, 1, 0, 0);
riverGraphics.fillRect(0, riverY - (riverHeight/2) - (edgeHeight/2), WORLD_W, edgeHeight);
riverGraphics.fillRect(0, riverY - (riverHeight/2) - (edgeHeight/2) + 10, WORLD_W, edgeHeight); // +10 nudge in
// Bottom Edge: Transparent -> Solid Brown (Downwards)
riverGraphics.fillGradientStyle(0x4e342e, 0x4e342e, 0x4e342e, 0x4e342e, 0, 0, 1, 1);
riverGraphics.fillRect(0, riverY + (riverHeight/2) - (edgeHeight/2), WORLD_W, edgeHeight);
riverGraphics.fillRect(0, riverY + (riverHeight/2) - (edgeHeight/2) - 10, WORLD_W, edgeHeight); // -10 nudge in
riverGraphics.setDepth(-49); // Above river
@@ -289,13 +322,13 @@ export default class GrassSceneClean extends Phaser.Scene {
});
// --- EDITOR MODE SYSTEM ---
this.editorEnabled = false;
this.editorEnabled = true; // Enabled by default per user request
this.selectedTile = 'path_tile_0';
this.editorGroup = this.add.group(); // Saved tiles
// Initialize Default State
this.selectedTile = 'path_tile_0';
this.editorEnabled = false;
// this.editorEnabled = false; // Duplicate init removed
// UI Palette (Hidden by default)
// FIX: Use viewport dimensions for UI
@@ -431,7 +464,7 @@ export default class GrassSceneClean extends Phaser.Scene {
this.ghostSprite.setVisible(state && this.selectedTile !== 'eraser_icon');
console.log("Editor:", state);
};
toggleEditor(false); // Start hidden
toggleEditor(true); // Start visible per user request
// Toggle Key
this.input.keyboard.on('keydown-E', () => {
@@ -646,7 +679,8 @@ export default class GrassSceneClean extends Phaser.Scene {
// 3. COLLIDERS
if (this.stream) this.physics.add.collider(this.kai, this.stream);
if (this.river) this.physics.add.collider(this.kai, this.river);
// Collider with riverCollider (invisible zone) instead of rotated sprite
if (this.riverCollider) this.physics.add.collider(this.kai, this.riverCollider);
// this.physics.add.collider(this.kai, this.obstaclesGroup);
// --- ANIMATIONS ---