🌱 Expanded Island + Procedural Growth System

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
This commit is contained in:
2026-02-10 17:41:58 +01:00
parent 7b8194caca
commit 2255bb7d41
2 changed files with 240 additions and 11 deletions

View File

@@ -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

View File

@@ -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 */