feat: Complete 2D Visual Overhaul - Isometric to Flat Top-Down

- NEW: Flat2DTerrainSystem.js (375 lines)
- NEW: map2d_data.js procedural map (221 lines)
- MODIFIED: GameScene async create, 2D terrain integration
- MODIFIED: Player.js flat 2D positioning
- MODIFIED: game.js disabled pixelArt for smooth rendering
- FIXED: 15+ bugs (updateCulling, isometric conversions, grid lines)
- ADDED: Phase 28 to TASKS.md
- DOCS: DNEVNIK.md session summary

Result: Working flat 2D game with Stardew Valley style!
Time: 5.5 hours
This commit is contained in:
2025-12-14 17:12:40 +01:00
parent c3dd39e1a6
commit 80bddf5d61
37 changed files with 8164 additions and 1800 deletions

View File

@@ -15,13 +15,14 @@ class GameScene extends Phaser.Scene {
};
}
create() {
async create() {
console.log('🎮 GameScene: Initialized!');
// Generate procedural textures
new TextureGenerator(this).generateAll();
InventoryIcons.create(this); // Override with flat 2D inventory icons
window.gameState.currentScene = 'GameScene';
window.gameState.gameScene = this; // Reference for global inventory helper
const width = this.cameras.main.width;
const height = this.cameras.main.height;
@@ -55,8 +56,25 @@ class GameScene extends Phaser.Scene {
// Inicializiraj terrain sistem - 100x100 mapa
console.log('🌍 Initializing terrain...');
try {
this.terrainSystem = new TerrainSystem(this, 100, 100);
this.terrainSystem.generate();
// 🎲 SEED-BASED GENERATION - Vsak krat ista mapa!
// Preveri če že imaš shranjeno spawn točko
let spawnPoint = localStorage.getItem('novafarma_spawn_point');
let terrainSeed = localStorage.getItem('novafarma_terrain_seed');
if (!terrainSeed) {
// PRVI LOGIN - generiraj nov seed
terrainSeed = Math.random().toString(36).substring(7);
localStorage.setItem('novafarma_terrain_seed', terrainSeed);
console.log('🆕 New world seed:', terrainSeed);
} else {
console.log('♻️ Loading existing world with seed:', terrainSeed);
}
// 🎨 2D FLAT TERRAIN SYSTEM (NEW!)
console.log('🎨 Initializing Flat 2D Terrain...');
this.terrainSystem = new Flat2DTerrainSystem(this);
await this.terrainSystem.generate();
console.log('✅ Flat 2D terrain ready!');
// Initialize Farming System
this.farmingSystem = new FarmingSystem(this);
@@ -115,8 +133,28 @@ class GameScene extends Phaser.Scene {
// Initial force update to render active tiles before first frame
this.terrainSystem.updateCulling(this.cameras.main);
// INITIALIZE FARM AREA (Starter Zone @ 20,20)
this.initializeFarmWorld();
// 🎲 RANDOM SPAWN POINT + 8x8 FARM (Prvi login)
if (!spawnPoint) {
// PRVI LOGIN - Random spawn točka
const spawnX = Math.floor(Math.random() * 80) + 10; // 10-90
const spawnY = Math.floor(Math.random() * 80) + 10; // 10-90
spawnPoint = `${spawnX},${spawnY}`;
localStorage.setItem('novafarma_spawn_point', spawnPoint);
console.log(`🎲 First login - Random spawn at (${spawnX}, ${spawnY})`);
console.log(`🏡 Creating 8x8 starter farm at spawn location...`);
// Ustvari 8x8 farmo na spawn točki
this.initializeFarmWorld(spawnX, spawnY);
} else {
// NI PRVI LOGIN - Naloži obstoječo spawn točko
const [spawnX, spawnY] = spawnPoint.split(',').map(Number);
console.log(`♻️ Returning player - spawn at (${spawnX}, ${spawnY})`);
// Obnovi farmo (če je shranjena)
this.initializeFarmWorld(spawnX, spawnY);
}
// 🍎 SADOVNJAK - Sadna Drevesa (ONEMOGOČENO)
// ========================================================
@@ -334,9 +372,17 @@ class GameScene extends Phaser.Scene {
console.error("Terrain system failed:", e);
}
// Dodaj igralca
// Dodaj igralca NA SPAWN TOČKI
console.log('👤 Initializing player...');
this.player = new Player(this, 50, 50, this.terrainOffsetX, this.terrainOffsetY);
const savedSpawn = localStorage.getItem('novafarma_spawn_point');
let playerSpawnX = 50, playerSpawnY = 50;
if (savedSpawn) {
[playerSpawnX, playerSpawnY] = savedSpawn.split(',').map(Number);
console.log(`👤 Spawning player at saved location: (${playerSpawnX}, ${playerSpawnY})`);
}
this.player = new Player(this, playerSpawnX, playerSpawnY, this.terrainOffsetX, this.terrainOffsetY);
// 🎯 SORTABLE OBJECTS GROUP - Za 2.5D Z-Sorting
console.log('🎯 Creating sortableObjects group for Z-sorting...');
@@ -438,6 +484,22 @@ class GameScene extends Phaser.Scene {
this.statsSystem = new StatsSystem(this);
this.inventorySystem = new InventorySystem(this);
// 🛠️ CRAFTING SYSTEM
this.craftingSystem = new CraftingSystem(this);
this.craftingSystem.loadRecipes().then(() => {
console.log('🛠️ Crafting system ready!');
// Create UI after recipes loaded
this.craftingUI = new CraftingUI(this);
// Add C key to toggle crafting UI
this.input.keyboard.on('keydown-C', () => {
if (this.craftingUI) {
this.craftingUI.toggle();
}
});
});
// ========================================================
// 💎 NEOMEJENI VIRI - Les in Kamen
// ========================================================
@@ -775,6 +837,18 @@ class GameScene extends Phaser.Scene {
setupCamera() {
const cam = this.cameras.main;
// 🎨 FLAT 2D CAMERA SETUP (NEW!)
const worldSize = 100 * 48; // 100 tiles × 48px = 4800px
cam.setBounds(0, 0, worldSize, worldSize);
cam.setZoom(1.0); // Default zoom for 2D
// Follow player
if (this.player && this.player.sprite) {
cam.startFollow(this.player.sprite, true, 0.1, 0.1);
}
console.log('📹 2D Camera setup:', worldSize, 'x', worldSize);
// Zoom kontrole (Mouse Wheel)
this.input.on('wheel', (pointer, gameObjects, deltaX, deltaY, deltaZ) => {
const zoomSpeed = 0.001;
@@ -843,6 +917,597 @@ class GameScene extends Phaser.Scene {
this.input.keyboard.on('keydown-M', () => {
if (this.soundManager) this.soundManager.toggleMute();
});
// 🌧️ WEATHER SYSTEM KEYS
this.input.keyboard.on('keydown-R', () => this.setWeather('rain'));
this.input.keyboard.on('keydown-SHIFT-S', () => this.setWeather('snow'));
this.input.keyboard.on('keydown-T', () => this.setWeather('storm'));
this.input.keyboard.on('keydown-F', () => this.setWeather('fog'));
this.input.keyboard.on('keydown-SHIFT-C', () => this.setWeather('clear'));
// Initialize weather system
this.initializeWeatherSystem();
// Initialize Weather UI Panel
this.weatherUI = new WeatherUI(this);
console.log('📊 Weather UI Panel created (press W to toggle)');
}
// 🌦️ COMPLETE WEATHER SYSTEM
initializeWeatherSystem() {
this.currentWeather = 'clear';
this.weatherIntensity = 1.0;
this.puddles = [];
this.splashes = [];
this.autoWeatherEnabled = false;
this.weatherCycleTimer = null;
// Load saved weather state
this.loadWeatherState();
console.log('🌦️ Weather system initialized');
console.log('💡 R = Rain | Shift+S = Snow | T = Storm | F = Fog | Shift+C = Clear');
console.log('💡 Shift+A = Toggle Auto Weather Cycle');
// Auto weather cycle toggle
this.input.keyboard.on('keydown-SHIFT-A', () => {
this.toggleAutoWeather();
});
// Intensity controls (+/-)
this.input.keyboard.on('keydown-PLUS', () => this.adjustIntensity(0.2));
this.input.keyboard.on('keydown-MINUS', () => this.adjustIntensity(-0.2));
}
toggleAutoWeather() {
this.autoWeatherEnabled = !this.autoWeatherEnabled;
if (this.autoWeatherEnabled) {
console.log('🔄 Auto weather cycle ENABLED');
this.startWeatherCycle();
} else {
console.log('⏸️ Auto weather cycle DISABLED');
if (this.weatherCycleTimer) {
this.weatherCycleTimer.destroy();
this.weatherCycleTimer = null;
}
}
this.saveWeatherState();
}
startWeatherCycle() {
// Weather cycle: Clear → Rain → Storm → Clear → Snow → Fog → Clear
const weatherSequence = ['clear', 'rain', 'storm', 'clear', 'snow', 'fog'];
const weatherDurations = {
clear: 120000, // 2 minutes
rain: 90000, // 1.5 minutes
storm: 60000, // 1 minute
snow: 90000, // 1.5 minutes
fog: 60000 // 1 minute
};
let currentIndex = 0;
const cycleWeather = () => {
const nextWeather = weatherSequence[currentIndex];
this.setWeather(nextWeather);
currentIndex = (currentIndex + 1) % weatherSequence.length;
const duration = weatherDurations[nextWeather] || 120000;
this.weatherCycleTimer = this.time.delayedCall(duration, () => {
if (this.autoWeatherEnabled) {
cycleWeather();
}
});
console.log(`🌦️ Auto weather: ${nextWeather} (${duration / 1000}s)`);
};
cycleWeather();
}
adjustIntensity(delta) {
this.weatherIntensity = Phaser.Math.Clamp(this.weatherIntensity + delta, 0.2, 2.0);
// Update current weather with new intensity
if (this.currentWeather !== 'clear' && this.currentWeather !== 'fog') {
this.setWeather(this.currentWeather); // Restart with new intensity
}
console.log(`🎚️ Weather intensity: ${(this.weatherIntensity * 100).toFixed(0)}%`);
this.saveWeatherState();
}
saveWeatherState() {
const state = {
currentWeather: this.currentWeather,
intensity: this.weatherIntensity,
autoEnabled: this.autoWeatherEnabled
};
localStorage.setItem('novafarma_weather_state', JSON.stringify(state));
}
loadWeatherState() {
const saved = localStorage.getItem('novafarma_weather_state');
if (saved) {
try {
const state = JSON.parse(saved);
this.currentWeather = state.currentWeather || 'clear';
this.weatherIntensity = state.intensity || 1.0;
this.autoWeatherEnabled = state.autoEnabled || false;
console.log('📂 Weather state loaded:', state);
// Restore weather (delayed to avoid initialization issues)
this.time.delayedCall(1000, () => {
if (this.currentWeather !== 'clear') {
this.setWeather(this.currentWeather);
}
if (this.autoWeatherEnabled) {
this.startWeatherCycle();
}
});
} catch (e) {
console.warn('⚠️ Failed to load weather state:', e);
}
}
}
setWeather(type) {
// Stop current weather
this.stopAllWeather();
this.currentWeather = type;
switch (type) {
case 'rain':
this.startRain();
break;
case 'snow':
this.startSnow();
break;
case 'storm':
this.startStorm();
break;
case 'fog':
this.startFog();
break;
case 'clear':
console.log('☀️ Clear weather');
break;
}
this.saveWeatherState();
}
stopAllWeather() {
// Stop all particle emitters
if (this.rainEmitter) this.rainEmitter.stop();
if (this.snowEmitter) this.snowEmitter.stop();
if (this.stormEmitter) this.stormEmitter.stop();
// Stop lightning
if (this.lightningTimer) {
this.lightningTimer.destroy();
this.lightningTimer = null;
}
// Stop puddle spawning
if (this.puddleTimer) {
this.puddleTimer.destroy();
this.puddleTimer = null;
}
// Fade out fog
if (this.fogOverlay) {
this.tweens.add({
targets: this.fogOverlay,
alpha: 0,
duration: 2000,
onComplete: () => {
if (this.fogOverlay) this.fogOverlay.destroy();
this.fogOverlay = null;
}
});
}
// Cleanup puddles
this.puddles.forEach(puddle => {
this.tweens.add({
targets: puddle,
alpha: 0,
duration: 3000,
onComplete: () => puddle.destroy()
});
});
this.puddles = [];
}
// ☔ RAIN SYSTEM
startRain() {
if (!this.rainEmitter) {
this.createRainParticles();
}
// Apply intensity
this.rainEmitter.setQuantity(Math.floor(3 * this.weatherIntensity));
this.rainEmitter.setFrequency(30 / this.weatherIntensity);
this.rainEmitter.start();
console.log('🌧️ Rain started!');
// Start puddle spawning
this.puddleTimer = this.time.addEvent({
delay: 3000 / this.weatherIntensity,
callback: () => this.spawnPuddle(),
loop: true
});
// Play rain sound
if (this.soundManager && this.soundManager.playRainSound) {
this.soundManager.playRainSound();
}
}
createRainParticles() {
if (!this.textures.exists('raindrop')) {
const graphics = this.make.graphics({ x: 0, y: 0, add: false });
graphics.fillStyle(0x88ccff, 1);
graphics.fillCircle(1, 2, 1);
graphics.generateTexture('raindrop', 2, 4);
graphics.destroy();
}
const cam = this.cameras.main;
this.rainEmitter = this.add.particles(0, 0, 'raindrop', {
x: { min: 0, max: cam.width },
y: -50,
lifespan: 3000,
speedY: { min: 400, max: 600 },
scale: { start: 1, end: 0.5 },
alpha: { start: 0.6, end: 0.2 },
quantity: 3,
frequency: 30,
blendMode: 'ADD',
// 🌊 DETECT WHEN RAINDROP HITS GROUND
deathCallback: (particle) => {
// Convert camera-relative position to world position
const worldX = particle.x + cam.scrollX;
const worldY = particle.y + cam.scrollY;
// Check if hit water tile
this.checkRainImpactOnWater(worldX, worldY);
}
});
this.rainEmitter.setScrollFactor(0);
this.rainEmitter.setDepth(999999);
this.rainEmitter.stop();
}
// ❄️ SNOW SYSTEM
startSnow() {
if (!this.snowEmitter) {
this.createSnowParticles();
}
this.snowEmitter.start();
console.log('❄️ Snow started!');
}
createSnowParticles() {
if (!this.textures.exists('snowflake')) {
const graphics = this.make.graphics({ x: 0, y: 0, add: false });
graphics.fillStyle(0xffffff, 1);
graphics.fillCircle(2, 2, 2);
graphics.generateTexture('snowflake', 4, 4);
graphics.destroy();
}
const cam = this.cameras.main;
this.snowEmitter = this.add.particles(0, 0, 'snowflake', {
x: { min: 0, max: cam.width },
y: -50,
lifespan: 8000,
speedY: { min: 50, max: 150 },
speedX: { min: -30, max: 30 },
scale: { start: 0.5, end: 1.5 },
alpha: { start: 0.8, end: 0.3 },
quantity: 2,
frequency: 80,
blendMode: 'ADD'
});
this.snowEmitter.setScrollFactor(0);
this.snowEmitter.setDepth(999999);
this.snowEmitter.stop();
}
// ⚡ STORM SYSTEM
startStorm() {
if (!this.stormEmitter) {
this.createStormParticles();
}
this.stormEmitter.start();
console.log('⛈️ Storm started!');
// Lightning flashes
this.lightningTimer = this.time.addEvent({
delay: Phaser.Math.Between(3000, 8000),
callback: () => this.triggerLightning(),
loop: true
});
// Puddles (faster spawn)
this.puddleTimer = this.time.addEvent({
delay: 2000,
callback: () => this.spawnPuddle(),
loop: true
});
}
createStormParticles() {
if (!this.textures.exists('raindrop')) {
this.createRainParticles();
}
const cam = this.cameras.main;
this.stormEmitter = this.add.particles(0, 0, 'raindrop', {
x: { min: 0, max: cam.width },
y: -50,
lifespan: 2000,
speedY: { min: 600, max: 900 },
speedX: { min: 50, max: 150 },
scale: { start: 1.5, end: 0.5 },
alpha: { start: 0.8, end: 0.3 },
quantity: 5,
frequency: 20,
blendMode: 'ADD'
});
this.stormEmitter.setScrollFactor(0);
this.stormEmitter.setDepth(999999);
this.stormEmitter.stop();
}
triggerLightning() {
// White flash overlay
const flash = this.add.rectangle(
this.cameras.main.scrollX,
this.cameras.main.scrollY,
this.cameras.main.width,
this.cameras.main.height,
0xffffff,
0.8
);
flash.setOrigin(0, 0);
flash.setScrollFactor(0);
flash.setDepth(1000000);
// Fade out
this.tweens.add({
targets: flash,
alpha: 0,
duration: 200,
onComplete: () => flash.destroy()
});
// Screen shake
this.cameras.main.shake(200, 0.005);
// Thunder sound (if available)
if (this.soundManager && this.soundManager.playThunderSound) {
this.time.delayedCall(300, () => {
this.soundManager.playThunderSound();
});
}
console.log('⚡ Lightning strike!');
}
// 🌫️ FOG SYSTEM
startFog() {
if (!this.fogOverlay) {
this.fogOverlay = this.add.rectangle(
0, 0,
this.cameras.main.width * 2,
this.cameras.main.height * 2,
0xcccccc,
0
);
this.fogOverlay.setOrigin(0, 0);
this.fogOverlay.setScrollFactor(0);
this.fogOverlay.setDepth(500000);
}
this.tweens.add({
targets: this.fogOverlay,
alpha: 0.4,
duration: 3000
});
console.log('🌫️ Fog started!');
}
// 💧 PUDDLES SYSTEM (Spawn on grass/dirt where rain lands!)
spawnPuddle() {
if (!this.terrainSystem) return;
const cam = this.cameras.main;
const worldX = cam.scrollX + Phaser.Math.Between(100, cam.width - 100);
const worldY = cam.scrollY + Phaser.Math.Between(100, cam.height - 100);
// 🎨 FLAT 2D CONVERSION (NEW!)
const tileSize = 48;
const x = Math.floor(worldX / tileSize);
const y = Math.floor(worldY / tileSize);
// Get tile type
const tile = this.terrainSystem.getTile(x, y);
// ONLY spawn puddles on grass or dirt!
if (!tile || (tile.type !== 'grass' && tile.type !== 'dirt' && tile.type !== 'farmland')) {
return; // Skip - not valid surface
}
// Limit max puddles
if (this.puddles.length >= 15) {
const oldest = this.puddles.shift();
if (oldest && oldest.active) oldest.destroy();
}
// Create puddle SPRITE (realistic!)
const puddle = this.add.image(worldX, worldY, 'luza_sprite');
puddle.setOrigin(0.5, 0.5);
puddle.setScale(1.5); // BIGGER - more visible!
puddle.setDepth(10); // ABOVE terrain
puddle.setScrollFactor(1);
puddle.setAlpha(0); // Start invisible
// Fade in
this.tweens.add({
targets: puddle,
alpha: 0.35,
duration: 2000
});
this.puddles.push(puddle);
// Auto cleanup after 30 seconds
this.time.delayedCall(30000, () => {
if (puddle && puddle.active) {
this.tweens.add({
targets: puddle,
alpha: 0,
duration: 3000,
onComplete: () => {
puddle.destroy();
const index = this.puddles.indexOf(puddle);
if (index > -1) this.puddles.splice(index, 1);
}
});
}
});
// Random splash effects
this.time.addEvent({
delay: Phaser.Math.Between(1000, 3000),
callback: () => {
if (puddle && puddle.active && (this.currentWeather === 'rain' || this.currentWeather === 'storm')) {
this.createSplash(puddle.x, puddle.y);
}
},
loop: true,
repeat: 5
});
}
// 🌊 CHECK IF RAIN HIT WATER TILE
checkRainImpactOnWater(worldX, worldY) {
if (!this.terrainSystem) return;
// 🎨 FLAT 2D CONVERSION (NEW!)
const tileSize = 48;
const x = Math.floor(worldX / tileSize);
const y = Math.floor(worldY / tileSize);
// Get tile at position
const tile = this.terrainSystem.getTile(x, y);
// If water tile, create ripple!
if (tile && tile.type === 'water') {
this.createWaterRipple(worldX, worldY);
}
// If grass/dirt, 3% chance to spawn puddle
else if (tile && (tile.type === 'grass' || tile.type === 'dirt' || tile.type === 'farmland')) {
if (Math.random() < 0.03) {
this.spawnPuddleAtLocation(worldX, worldY);
}
}
}
// 💧 CREATE WATER RIPPLE EFFECT
createWaterRipple(x, y) {
// Small expanding circle on water surface
const ripple = this.add.circle(x, y, 2, 0xffffff, 0.5);
ripple.setDepth(500); // Above water tiles
ripple.setScrollFactor(1); // World-bound
this.tweens.add({
targets: ripple,
radius: 10,
alpha: 0,
duration: 400,
ease: 'Quad.easeOut',
onComplete: () => ripple.destroy()
});
}
// 💧 SPAWN PUDDLE AT EXACT LOCATION (from rain impact)
spawnPuddleAtLocation(worldX, worldY) {
// Limit max puddles
if (this.puddles.length >= 15) {
// Remove oldest puddle
const oldest = this.puddles.shift();
if (oldest && oldest.active) oldest.destroy();
}
// Create puddle SPRITE (realistic!)
const puddle = this.add.image(worldX, worldY, 'luza_sprite');
puddle.setOrigin(0.5, 0.5);
puddle.setScale(1.5); // BIGGER - more visible!
puddle.setDepth(10); // ABOVE terrain
puddle.setScrollFactor(1);
puddle.setAlpha(0); // Start invisible
// Fade in
this.tweens.add({
targets: puddle,
alpha: 0.35,
duration: 2000
});
this.puddles.push(puddle);
// Auto cleanup after 30 seconds
this.time.delayedCall(30000, () => {
if (puddle && puddle.active) {
this.tweens.add({
targets: puddle,
alpha: 0,
duration: 3000,
onComplete: () => {
puddle.destroy();
const index = this.puddles.indexOf(puddle);
if (index > -1) this.puddles.splice(index, 1);
}
});
}
});
}
// 💦 SPLASH EFFECT (Ripples)
createSplash(x, y) {
// Concentric circles
for (let i = 0; i < 3; i++) {
this.time.delayedCall(i * 100, () => {
const circle = this.add.circle(x, y, 3, 0xffffff, 0.5);
circle.setDepth(2);
this.tweens.add({
targets: circle,
radius: 20 + (i * 5),
alpha: 0,
duration: 600,
onComplete: () => circle.destroy()
});
});
}
}
update(time, delta) {
@@ -862,9 +1527,13 @@ class GameScene extends Phaser.Scene {
});
}
// Weather UI Update
if (this.weatherUI) this.weatherUI.update();
// Update Systems
if (this.terrainSystem) this.terrainSystem.update(time, delta); // Water animation!
if (this.statsSystem) this.statsSystem.update(delta);
if (this.craftingSystem) this.craftingSystem.update(delta); // 🛠️ Crafting progress
if (this.lootSystem) this.lootSystem.update(delta);
if (this.interactionSystem) this.interactionSystem.update(delta);
if (this.farmingSystem) this.farmingSystem.update(delta);
@@ -948,26 +1617,30 @@ class GameScene extends Phaser.Scene {
// Parallax Logic
if (this.parallaxSystem && this.player) {
const playerPos = this.player.getPosition();
const screenPos = this.iso.toScreen(playerPos.x, playerPos.y);
this.parallaxSystem.update(
screenPos.x + this.terrainOffsetX,
screenPos.y + this.terrainOffsetY
);
// 🎨 FLAT 2D (NEW!) - Direct position, no conversion
const tileSize = 48;
const screenX = playerPos.x * tileSize + tileSize / 2;
const screenY = playerPos.y * tileSize + tileSize / 2;
this.parallaxSystem.update(screenX, screenY);
}
// Terrain Culling & Update
// Terrain Update
if (this.terrainSystem) {
this.terrainSystem.updateCulling(this.cameras.main);
// Note: Flat2D doesn't need culling (already optimized)
// this.terrainSystem.updateCulling(this.cameras.main);
this.terrainSystem.update(delta);
}
// Clouds
if (this.clouds) {
for (const cloud of this.clouds) {
cloud.sprite.x += cloud.speed * (delta / 1000);
if (cloud.sprite.x > this.terrainOffsetX + 2000) {
cloud.sprite.x = this.terrainOffsetX - 2000;
cloud.sprite.y = Phaser.Math.Between(0, 1000);
if (cloud && cloud.sprite) {
cloud.sprite.x += cloud.speed * (delta / 1000);
if (cloud.sprite.x > this.terrainOffsetX + 2000) {
cloud.sprite.x = this.terrainOffsetX - 2000;
cloud.sprite.y = Phaser.Math.Between(0, 1000);
}
}
}
}
@@ -1138,12 +1811,12 @@ class GameScene extends Phaser.Scene {
if (this.saveSystem) this.saveSystem.loadGame();
}
initializeFarmWorld() {
console.log('🌾 Initializing Farm Area (Starter Zone)...');
initializeFarmWorld(spawnX = 20, spawnY = 20) {
console.log(`🌾 Initializing 8x8 Farm Area at (${spawnX}, ${spawnY})...`);
const farmX = 20; // Farm center
const farmY = 20;
const farmRadius = 8;
const farmX = spawnX; // Farm center (custom spawn)
const farmY = spawnY;
const farmRadius = 4; // 8x8 = radius 4 (4 tiles in each direction)
// 1. Clear farm area (odstrani drevesa in kamne)
for (let x = farmX - farmRadius; x <= farmX + farmRadius; x++) {
@@ -1154,27 +1827,25 @@ class GameScene extends Phaser.Scene {
if (this.terrainSystem.decorationsMap.has(key)) {
this.terrainSystem.removeDecoration(x, y);
}
// Make it DIRT for farming
// Change terrain to grass
if (this.terrainSystem.tiles[y] && this.terrainSystem.tiles[y][x]) {
this.terrainSystem.tiles[y][x].type = 'dirt';
this.terrainSystem.tiles[y][x].type = 'grass';
this.terrainSystem.tiles[y][x].solid = false;
if (this.terrainSystem.tiles[y][x].sprite) {
this.terrainSystem.tiles[y][x].sprite.setTexture('dirt');
this.terrainSystem.tiles[y][x].sprite.setTint(0xffffff); // Clear tint
this.terrainSystem.tiles[y][x].sprite.setTexture('grass');
this.terrainSystem.tiles[y][x].sprite.clearTint();
}
}
}
}
}
// 2. Place starter resources (chest s semeni) - REMOVED PER USER REQUEST (Floating chest bug)
// this.terrainSystem.placeStructure(farmX + 3, farmY + 3, 'chest');
// 3. Place FULL FENCE around farm
// console.log('🚧 Building Farm Fence...');
// const minX = farmX - farmRadius;
// const maxX = farmX + farmRadius;
// const minY = farmY - farmRadius;
// const maxY = farmY + farmRadius;
// 2. Optional: Add fence around farm (commented out)
// const minX = farmX - farmRadius - 1;
// const maxX = farmX + farmRadius + 1;
// const minY = farmY - farmRadius - 1;
// const maxY = farmY + farmRadius + 1;
// // Top and bottom horizontal fences
// for (let x = minX; x <= maxX; x++) {
@@ -1192,7 +1863,7 @@ class GameScene extends Phaser.Scene {
// }
// }
console.log('✅ Farm Area Initialized at (20,20)');
console.log(`✅ 8x8 Farm Area Initialized at (${spawnX},${spawnY})`);
}
// ========================================================