From 2255bb7d41555886fb93dc3ef80dde2a213af1e4 Mon Sep 17 00:00:00 2001 From: David Kotnik Date: Tue, 10 Feb 2026 17:41:58 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=B1=20Expanded=20Island=20+=20Procedur?= =?UTF-8?q?al=20Growth=20System?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ISLAND EXPANSION: - Increased from 20x20 to 50x50 tiles (6400x6400px) - World size: 10400x10400px (with ocean buffer) - Irregular edges (procedural jitter system maintained) PROCEDURAL GROWTH SYSTEM: - Soil moisture grid (50x50) - tracks wet/dry tiles - Grass growth: 30% chance if soil is wet - Tree saplings: 10 placed on island edges - Tree aging: sapling → medium (3 days) → large (7 days) - Rainfall: 40% chance daily, wets 60% of tiles LAYER SYSTEM (Z-ORDER FIX): - LAYER_GROUND (-100): Foundation tiles - LAYER_VEGETATION (1): Grass, bushes - below characters! - LAYER_TREES (2): Trees - LAYER_CHARACTERS (10): Kai, zombies - walks BETWEEN vegetation GROWTH MECHANICS: - Morning check every 60 seconds (1 in-game day) - Grass fades in smoothly (2s animation) - Trees progress: faza_1 → faza_2 → veliko - Random grass types & sizes for variety NATURE TAKES OVER: - Island evolves procedurally over time - Dark Gothic aesthetic maintained - Living, breathing environment Date: 2026-02-10 17:42 --- .../ASSET_GENERATION_BATCH_PLAN.md | 32 ++- .../src/scenes/GrassScene_Clean.js | 219 +++++++++++++++++- 2 files changed, 240 insertions(+), 11 deletions(-) diff --git a/nova farma TRAE/dokumentacija/ASSET_GENERATION_BATCH_PLAN.md b/nova farma TRAE/dokumentacija/ASSET_GENERATION_BATCH_PLAN.md index f2d5c86d9..f48dbf40d 100644 --- a/nova farma TRAE/dokumentacija/ASSET_GENERATION_BATCH_PLAN.md +++ b/nova farma TRAE/dokumentacija/ASSET_GENERATION_BATCH_PLAN.md @@ -334,14 +334,41 @@ --- +## 🟣 BATCH 13: POWER GRID SYSTEM (10 assets) + +### **22. ELECTRICAL INFRASTRUCTURE** +**Files to generate/copy:** +- `power_pole.png` - Power pole sprite (copy from `objekt_elektricni_drog_predelan_svetlejsi.png`) +- `cable_horizontal.png` - Horizontal cable segment +- `cable_vertical.png` - Vertical cable segment +- `cable_corner_tl.png` - Top-left corner cable +- `cable_corner_tr.png` - Top-right corner cable +- `cable_corner_bl.png` - Bottom-left corner cable +- `cable_corner_br.png` - Bottom-right corner cable +- `cable_spark_effect.png` - Electric spark particles (⚡ travel along cables) +- `power_indicator_on.png` - Green glow indicator (building is powered) +- `power_indicator_off.png` - Red indicator (no power) + +**Reference:** `objekt_cevi_in_kabli_set.png` (240KB cable set) + +**Gameplay:** +- Player places power poles (range: 10 tiles) +- Cables auto-connect between poles +- Visual feedback: sparks travel along active cables +- Buildings show powered status (green glow vs red) + +**Priority:** MEDIUM (Faza 1 feature - Generator system extension) + +--- + ## 📊 GENERATION SUMMARY: -**TOTAL ASSETS TO GENERATE:** ~150-180 individual files +**TOTAL ASSETS TO GENERATE:** ~160-190 individual files **By Priority:** - 🔴 **CRITICAL:** 35 assets (Zombies, Kai, Day/Night, Fog, Polaroid) - 🟡 **HIGH:** 45 assets (UI, Structures, Tools) -- 🟢 **MEDIUM:** 40 assets (Animals, Crops, Water system) +- 🟢 **MEDIUM:** 50 assets (Animals, Crops, Water, Power Grid) - 🔵 **LOW:** 30-50 assets (Fish, Insects, Couriers) --- @@ -371,6 +398,7 @@ 6. Batch 4: UI systems (Radio, Twin Bond, Taming) 7. Batch 11: Structures 8. Batch 12: Tools & Items +9. Batch 13: Power Grid System ### **Week 3:** 9. Batch 5: Water system diff --git a/nova farma TRAE/src/scenes/GrassScene_Clean.js b/nova farma TRAE/src/scenes/GrassScene_Clean.js index db9566ba3..cf1360ba4 100644 --- a/nova farma TRAE/src/scenes/GrassScene_Clean.js +++ b/nova farma TRAE/src/scenes/GrassScene_Clean.js @@ -5,6 +5,25 @@ export default class GrassSceneClean extends Phaser.Scene { // Class-level constants this.TILE_SIZE = 128; // Standard grid size this.GROUND_TILE_SIZE = 128; // Standard grid size (Style 32) + + // === EXPANDED ISLAND SYSTEM === + this.ISLAND_GRID_SIZE = 50; // 50x50 tile grid + this.ISLAND_WORLD_SIZE = this.ISLAND_GRID_SIZE * this.TILE_SIZE; // 6400px + + // === PROCEDURAL GROWTH SYSTEM === + this.GRASS_GROWTH_CHANCE = 0.30; // 30% if soil is wet + this.TREE_SAPLING_COUNT = 10; // Initial saplings + + // === LAYER SYSTEM (Z-ORDER) === + this.LAYER_GROUND = -100; + this.LAYER_VEGETATION = 1; // Grass, bushes + this.LAYER_TREES = 2; // Trees + this.LAYER_CHARACTERS = 10; // Kai, zombies + + // === GROWTH STATE === + this.soilGrid = []; // 50x50 grid for moisture tracking + this.grassTiles = []; // Dynamic grass instances + this.treeSaplings = []; // Growing trees } preload() { @@ -107,18 +126,24 @@ export default class GrassSceneClean extends Phaser.Scene { // For now, I'll use a simple console notification and prepare the code for tree_hit.mp3 / tree_fall.mp3 } - // Island Dimensions (Playable Area) - const ISLAND_WIDTH_TILES = 20; - const ISLAND_HEIGHT_TILES = 20; - const ISLAND_W = ISLAND_WIDTH_TILES * this.TILE_SIZE; // 2560 px - const ISLAND_H = ISLAND_HEIGHT_TILES * this.TILE_SIZE; // 2560 px + // === EXPANDED ISLAND DIMENSIONS (50x50 Grid) === + const ISLAND_W = this.ISLAND_WORLD_SIZE; // 6400px (50 * 128) + const ISLAND_H = this.ISLAND_WORLD_SIZE; // 6400px - // World/Ocean Dimensions (Large Buffer) - const WORLD_W = 10000; - const WORLD_H = 10000; - const ISLAND_X = (WORLD_W - ISLAND_W) / 2; + // World/Ocean Dimensions (Large Buffer around island) + const WORLD_W = ISLAND_W + 4000; // 10400px total + const WORLD_H = ISLAND_H + 4000; // 10400px total + const ISLAND_X = (WORLD_W - ISLAND_W) / 2; // Center island const ISLAND_Y = (WORLD_H - ISLAND_H) / 2; + // Store for use throughout scene + this.worldWidth = WORLD_W; + this.worldHeight = WORLD_H; + this.islandX = ISLAND_X; + this.islandY = ISLAND_Y; + this.islandWidth = ISLAND_W; + this.islandHeight = ISLAND_H; + // Set World Bounds to Island only (Hard Stop) this.physics.world.setBounds(ISLAND_X, ISLAND_Y, ISLAND_W, ISLAND_H); @@ -994,6 +1019,30 @@ export default class GrassSceneClean extends Phaser.Scene { this.fog2.setTint(0x00ff00); // GREEN */ // === FARMING & FOG REMOVED - Ultra Clean === + + // === PROCEDURAL GROWTH SYSTEM INITIALIZATION === + console.log('🌱 Initializing Procedural Growth System...'); + + // Initialize soil moisture grid + this.initSoilGrid(); + + // Place tree saplings on island edges + this.placeTreeSaplings(); + + // Set up morning growth timer (every 60 seconds = 1 in-game day) + this.time.addEvent({ + delay: 60000, // 60 seconds + callback: () => { + this.morningGrowthCheck(); + // 40% chance of rainfall each day + if (Math.random() < 0.4) { + this.triggerRainfall(); + } + }, + loop: true + }); + + console.log('✅ Growth system ready - Island will evolve over time!'); } @@ -1206,6 +1255,158 @@ export default class GrassSceneClean extends Phaser.Scene { } } + // === PROCEDURAL GROWTH SYSTEM === + + /** Initialize soil moisture grid (50x50) */ + initSoilGrid() { + for (let y = 0; y < this.ISLAND_GRID_SIZE; y++) { + this.soilGrid[y] = []; + for (let x = 0; x < this.ISLAND_GRID_SIZE; x++) { + // Random initial moisture: 0=dry, 1=wet + this.soilGrid[y][x] = Math.random() > 0.7 ? 1 : 0; + } + } + console.log(`✅ Soil Grid initialized (${this.ISLAND_GRID_SIZE}x${this.ISLAND_GRID_SIZE})`); + } + + /** Place tree saplings on island edges */ + placeTreeSaplings() { + const edgeBuffer = 2; // Tiles from edge + const placed = []; + + while (placed.length < this.TREE_SAPLING_COUNT) { + // Random edge position + const edge = Math.floor(Math.random() * 4); // 0=top, 1=right, 2=bottom, 3=left + let gridX, gridY; + + if (edge === 0) { // Top edge + gridX = Math.floor(Math.random() * this.ISLAND_GRID_SIZE); + gridY = edgeBuffer; + } else if (edge === 1) { // Right edge + gridX = this.ISLAND_GRID_SIZE - edgeBuffer; + gridY = Math.floor(Math.random() * this.ISLAND_GRID_SIZE); + } else if (edge === 2) { // Bottom edge + gridX = Math.floor(Math.random() * this.ISLAND_GRID_SIZE); + gridY = this.ISLAND_GRID_SIZE - edgeBuffer; + } else { // Left edge + gridX = edgeBuffer; + gridY = Math.floor(Math.random() * this.ISLAND_GRID_SIZE); + } + + // Check if already placed here + if (placed.some(p => p.gridX === gridX && p.gridY === gridY)) continue; + + // World coordinates + const worldX = this.islandX + (gridX * this.TILE_SIZE) + (this.TILE_SIZE / 2); + const worldY = this.islandY + (gridY * this.TILE_SIZE) + (this.TILE_SIZE / 2); + + // Create sapling (small tree) + const sapling = this.add.image(worldX, worldY, 'drevo_faza_1') + .setScale(0.4) // Small sapling + .setDepth(this.LAYER_TREES) + .setAlpha(0.8); + + this.treeSaplings.push({ + sprite: sapling, + gridX, + gridY, + age: 0, // Days old + stage: 1 // Growth stage (1-3) + }); + + placed.push({ gridX, gridY }); + } + + console.log(`🌱 Placed ${this.treeSaplings.length} tree saplings on edges`); + } + + /** Morning growth check - called every in-game morning */ + morningGrowthCheck() { + let grassGrown = 0; + let treesGrown = 0; + + // === GRASS GROWTH === + for (let y = 0; y < this.ISLAND_GRID_SIZE; y++) { + for (let x = 0; x < this.ISLAND_GRID_SIZE; x++) { + // Skip if already has grass + if (this.grassTiles.some(g => g.gridX === x && g.gridY === y)) continue; + + // Check soil moisture + if (this.soilGrid[y][x] === 1) { // Wet soil + // 30% chance to grow grass + if (Math.random() < this.GRASS_GROWTH_CHANCE) { + this.growGrass(x, y); + grassGrown++; + } + } + } + } + + // === TREE GROWTH === + this.treeSaplings.forEach(tree => { + tree.age++; + + // Growth stages: 1→2 at 3 days, 2→3 at 7 days + if (tree.age === 3 && tree.stage === 1) { + tree.stage = 2; + tree.sprite.setTexture('drevo_faza_2').setScale(0.7); + treesGrown++; + } else if (tree.age === 7 && tree.stage === 2) { + tree.stage = 3; + tree.sprite.setTexture('drevo_veliko').setScale(1.0).setAlpha(1.0); + treesGrown++; + } + }); + + if (grassGrown > 0 || treesGrown > 0) { + console.log(`🌿 Morning Growth: +${grassGrown} grass, ${treesGrown} trees matured`); + } + } + + /** Grow grass at grid position */ + growGrass(gridX, gridY) { + const worldX = this.islandX + (gridX * this.TILE_SIZE) + (this.TILE_SIZE / 2); + const worldY = this.islandY + (gridY * this.TILE_SIZE) + (this.TILE_SIZE / 2); + + // Random grass sprite (use available grass assets) + const grassTypes = ['grass_ref_1', 'grass_cluster_dense', 'grass_cluster_flowery']; + const grassType = Phaser.Utils.Array.GetRandom(grassTypes); + + const grass = this.add.image(worldX, worldY, grassType) + .setScale(0.6 + Math.random() * 0.4) // Size variation + .setDepth(this.LAYER_VEGETATION) // Layer 1 - below characters! + .setAlpha(0); + + // Fade in animation + this.tweens.add({ + targets: grass, + alpha: 1, + duration: 2000, + ease: 'Quad.easeOut' + }); + + this.grassTiles.push({ + sprite: grass, + gridX, + gridY + }); + } + + /** Trigger rainfall - wets soil randomly */ + triggerRainfall() { + let wetTiles = 0; + for (let y = 0; y < this.ISLAND_GRID_SIZE; y++) { + for (let x = 0; x < this.ISLAND_GRID_SIZE; x++) { + // 60% chance to wet tile + if (Math.random() < 0.6) { + this.soilGrid[y][x] = 1; + wetTiles++; + } + } + } + console.log(`🌧️ Rainfall: ${wetTiles} tiles wet`); + } + // --- AUTO-TILING SYSTEM (REMOVED) --- /* Removed for cleanup */