This commit is contained in:
2025-12-12 02:41:00 +01:00
parent e15b429e75
commit 84b07bb433
13 changed files with 1917 additions and 76 deletions

View File

@@ -0,0 +1,174 @@
// ========================================================
// PRIMERI UPORABE SISTEMA ZA POSTAVITEV OGRAJ
// ========================================================
//
// Ta datoteka vsebuje primere, kako uporabljati BuildSystem
// za ročno postavitev ograj na natančne koordinate.
//
// KAKO UPORABITI:
// 1. V GameScene.js dodaj: import './examples/FencePlacementExample.js';
// 2. V create() metodi pokliči: this.setupFenceExamples();
// ========================================================
/**
* Dodaj to metodo v GameScene.js za testiranje postavitve ograj.
*/
export function setupFenceExamples(scene) {
// Počakaj, da se BuildSystem inicializira
if (!scene.buildSystem) {
console.error('❌ BuildSystem ni inicializiran!');
return;
}
console.log('🔧 Inicializacija primerov postavitve ograj...');
// ========================================================
// PRIMER 1: Postavitev ene same ograje
// ========================================================
scene.buildSystem.placeSingleFence(50, 30, 'fence_horizontal', false);
// ========================================================
// PRIMER 2: Postavitev kratke linije ograj (vodoravno)
// ========================================================
for (let i = 0; i < 5; i++) {
scene.buildSystem.placeSingleFence(50 + i, 32, 'fence_horizontal', false);
}
// ========================================================
// PRIMER 3: Postavitev navpične linije ograj
// ========================================================
for (let i = 0; i < 5; i++) {
scene.buildSystem.placeSingleFence(48, 30 + i, 'fence_vertical', false);
}
// ========================================================
// PRIMER 4: Uporaba placeFenceLine (Bresenhamov algoritem)
// ========================================================
scene.buildSystem.placeFenceLine(40, 40, 45, 45, 'fence_post', false);
// ========================================================
// PRIMER 5: Postavitev pravokotnika ograj (10x8)
// ========================================================
scene.buildSystem.placeFenceRectangle(30, 50, 10, 8, 'fence_horizontal', false);
// ========================================================
// PRIMER 6: Postavitev ograj okoli farme (primer)
// ========================================================
// Če želite ograditi celotno farmo (100x100), uporabite:
// scene.buildSystem.placeFenceRectangle(0, 0, 100, 100, 'fence_horizontal', false);
// ========================================================
// PRIMER 7: Različni tipi ograj
// ========================================================
// Razpoložljivi tipi ograj:
// - 'fence' (stara ograja)
// - 'fence_post' (steber)
// - 'fence_horizontal' (vodoravna →)
// - 'fence_vertical' (navpična ↓)
// - 'fence_corner' (vogal ⌞)
scene.buildSystem.placeSingleFence(60, 30, 'fence_post', false);
scene.buildSystem.placeSingleFence(61, 30, 'fence_horizontal', false);
scene.buildSystem.placeSingleFence(62, 30, 'fence_vertical', false);
scene.buildSystem.placeSingleFence(63, 30, 'fence_corner', false);
// ========================================================
// PRIMER 8: Postavitev z porabo virov
// ========================================================
// Če želite, da se viri porabijo pri postavitvi:
// scene.buildSystem.placeSingleFence(70, 30, 'fence_horizontal', true);
// OPOMBA: To bo preverilo, ali ima igralec dovolj lesa!
console.log('✅ Primeri postavitve ograj so bili izvedeni!');
}
/**
* Napredni primer: Ustvari labirint iz ograj
*/
export function createFenceMaze(scene, startX, startY, size = 20) {
if (!scene.buildSystem) return;
console.log('🌀 Ustvarjanje labirinta iz ograj...');
// Zunanji rob
scene.buildSystem.placeFenceRectangle(startX, startY, size, size, 'fence_horizontal', false);
// Notranje stene (primer)
for (let i = 2; i < size - 2; i += 4) {
scene.buildSystem.placeFenceLine(
startX + i,
startY + 2,
startX + i,
startY + size - 3,
'fence_vertical',
false
);
}
console.log('✅ Labirint ustvarjen!');
}
/**
* Napredni primer: Ustvari spiralo iz ograj
*/
export function createFenceSpiral(scene, centerX, centerY, maxRadius = 10) {
if (!scene.buildSystem) return;
console.log('🌀 Ustvarjanje spirale iz ograj...');
let x = centerX;
let y = centerY;
let dx = 0;
let dy = -1;
let segment_length = 1;
let segment_passed = 0;
for (let i = 0; i < maxRadius * maxRadius; i++) {
scene.buildSystem.placeSingleFence(x, y, 'fence_post', false);
x += dx;
y += dy;
segment_passed++;
if (segment_passed === segment_length) {
segment_passed = 0;
// Zavij desno
const temp = dx;
dx = -dy;
dy = temp;
if (dy === 0) {
segment_length++;
}
}
}
console.log('✅ Spirala ustvarjena!');
}
// ========================================================
// KAKO UPORABITI TE PRIMERE V GAMESCENE.JS:
// ========================================================
/*
// 1. Na vrhu GameScene.js dodaj import:
import { setupFenceExamples, createFenceMaze, createFenceSpiral } from './examples/FencePlacementExample.js';
// 2. V create() metodi, po inicializaciji BuildSystem:
create() {
// ... ostala koda ...
this.buildSystem = new BuildSystem(this);
// Pokliči primere (opcijsko):
setupFenceExamples(this);
// Ali ustvari labirint:
// createFenceMaze(this, 20, 20, 30);
// Ali ustvari spiralo:
// createFenceSpiral(this, 50, 50, 15);
}
*/

View File

@@ -66,6 +66,45 @@ class GameScene extends Phaser.Scene {
this.buildSystem = new BuildSystem(this);
console.log('🏗️ Build system initialized!');
// ========================================================
// 🏗️ TESTNI PRIMERI - Postavitev Ograj (ONEMOGOČENO)
// ========================================================
// Odstrani // pred vrsticami, če želiš videti testne ograje!
// ALI pritisni B v igri za Build Mode in postavljaj ročno!
// PRIMER 1: Ena sama ograja
// this.buildSystem.placeSingleFence(50, 50, 'fence_post', false);
// PRIMER 2: Vodoravna linija ograj (10 ograj)
// for (let i = 0; i < 10; i++) {
// this.buildSystem.placeSingleFence(45 + i, 52, 'fence_horizontal', false);
// }
// PRIMER 3: Navpična linija ograj (10 ograj)
// for (let i = 0; i < 10; i++) {
// this.buildSystem.placeSingleFence(43, 48 + i, 'fence_vertical', false);
// }
// PRIMER 4: Majhen pravokotnik (8x6)
// this.buildSystem.placeFenceRectangle(60, 45, 8, 6, 'fence_post', false);
// PRIMER 5: Diagonalna linija (Bresenham)
// this.buildSystem.placeFenceLine(30, 30, 40, 40, 'fence_corner', false);
// PRIMER 6: Večji pravokotnik (20x15)
// this.buildSystem.placeFenceRectangle(20, 60, 20, 15, 'fence_horizontal', false);
// PRIMER 7: Različni tipi ograj v vrsti
// this.buildSystem.placeSingleFence(70, 50, 'fence', false);
// this.buildSystem.placeSingleFence(71, 50, 'fence_post', false);
// this.buildSystem.placeSingleFence(72, 50, 'fence_horizontal', false);
// this.buildSystem.placeSingleFence(73, 50, 'fence_vertical', false);
// this.buildSystem.placeSingleFence(74, 50, 'fence_corner', false);
// console.log('✅ Testne ograje postavljene! Preveri mapo.');
// ========================================================
// Terrain offset
this.terrainOffsetX = width / 2;
this.terrainOffsetY = 100;
@@ -79,6 +118,136 @@ class GameScene extends Phaser.Scene {
// INITIALIZE FARM AREA (Starter Zone @ 20,20)
this.initializeFarmWorld();
// 🍎 SADOVNJAK - Sadna Drevesa (ONEMOGOČENO)
// ========================================================
// Odstrani // če želiš sadovnjak
/*
console.log('🍎 Ustvarjam sadovnjak...');
const orchardX = 35; // Lokacija sadovnjaka
const orchardY = 60;
const orchardSize = 10; // 10x10 območje
// 1. Očisti območje (odstrani obstoječe drevese)
for (let x = orchardX; x < orchardX + orchardSize; x++) {
for (let y = orchardY; y < orchardY + orchardSize; y++) {
if (x >= 0 && x < 100 && y >= 0 && y < 100) {
const key = `${x},${y}`;
if (this.terrainSystem.decorationsMap.has(key)) {
this.terrainSystem.removeDecoration(x, y);
}
// Spremeni teren v travo
if (this.terrainSystem.tiles[y] && this.terrainSystem.tiles[y][x]) {
this.terrainSystem.tiles[y][x].type = 'grass';
if (this.terrainSystem.tiles[y][x].sprite) {
this.terrainSystem.tiles[y][x].sprite.setTexture('grass');
this.terrainSystem.tiles[y][x].sprite.clearTint();
}
}
}
}
}
// 2. Dodaj SADIKE (tree_sapling) - bodo rasle v sadna drevesa!
const fruitTreeTypes = ['tree_apple', 'tree_orange', 'tree_cherry'];
let treeCount = 0;
const saplingPositions = []; // Shrani pozicije za ograje
for (let x = orchardX + 1; x < orchardX + orchardSize - 1; x += 2) {
for (let y = orchardY + 1; y < orchardY + orchardSize - 1; y += 2) {
if (x >= 0 && x < 100 && y >= 0 && y < 100) {
// Dodaj SADIKO (bo rasla v sadno drevo)
this.terrainSystem.addDecoration(x, y, 'tree_sapling');
saplingPositions.push({ x, y, type: fruitTreeTypes[treeCount % fruitTreeTypes.length] });
treeCount++;
}
}
}
// 3. Dodaj LESENO OGRAJO okoli vsakega drevesa (3x3 kvadrat)
saplingPositions.forEach(pos => {
// Ograja okoli drevesa (3x3)
const fencePositions = [
// Zgornja vrstica
{ x: pos.x - 1, y: pos.y - 1 },
{ x: pos.x, y: pos.y - 1 },
{ x: pos.x + 1, y: pos.y - 1 },
// Spodnja vrstica
{ x: pos.x - 1, y: pos.y + 1 },
{ x: pos.x, y: pos.y + 1 },
{ x: pos.x + 1, y: pos.y + 1 },
// Leva stran
{ x: pos.x - 1, y: pos.y },
// Desna stran
{ x: pos.x + 1, y: pos.y }
];
fencePositions.forEach(fPos => {
if (fPos.x >= 0 && fPos.x < 100 && fPos.y >= 0 && fPos.y < 100) {
this.buildSystem.placeSingleFence(fPos.x, fPos.y, 'fence_horizontal', false);
}
});
});
// 4. Dodaj ZUNANJO OGRAJO okoli celega sadovnjaka
this.buildSystem.placeFenceRectangle(
orchardX - 1,
orchardY - 1,
orchardSize + 2,
orchardSize + 2,
'fence_post',
false
);
// 5. Dodaj cvetje med ograjami
for (let x = orchardX; x < orchardX + orchardSize; x++) {
for (let y = orchardY; y < orchardY + orchardSize; y++) {
if (x >= 0 && x < 100 && y >= 0 && y < 100) {
const key = `${x},${y}`;
if (!this.terrainSystem.decorationsMap.has(key) && Math.random() > 0.85) {
this.terrainSystem.addDecoration(x, y, 'flowers_new');
}
}
}
}
// 6. RAST DREVES - Sadike bodo rasle v sadna drevesa!
// Nastavi timer za rast (vsako drevo raste po 30 sekundah)
saplingPositions.forEach((pos, index) => {
this.time.delayedCall(30000 + (index * 2000), () => {
const key = `${pos.x},${pos.y}`;
// Odstrani sadiko
if (this.terrainSystem.decorationsMap.has(key)) {
this.terrainSystem.removeDecoration(pos.x, pos.y);
}
// Dodaj SADNO DREVO
this.terrainSystem.addDecoration(pos.x, pos.y, pos.type);
// Animacija rasti
if (this.terrainSystem.visibleDecorations.has(key)) {
const sprite = this.terrainSystem.visibleDecorations.get(key);
sprite.setScale(0.01);
this.tweens.add({
targets: sprite,
scaleX: 0.04,
scaleY: 0.04,
duration: 2000,
ease: 'Bounce.out'
});
}
console.log(`🌳 Drevo zraslo: ${pos.type} na (${pos.x}, ${pos.y})`);
});
});
console.log(`✅ Sadovnjak ustvarjen na (${orchardX}, ${orchardY}) - ${treeCount} sadik (bodo rasle v 30s)`);
*/
// ========================================================
// CITY CONTENT: Ruins, Chests, Spawners
console.log('🏚️ Generating City Content...');
@@ -248,6 +417,17 @@ class GameScene extends Phaser.Scene {
this.statsSystem = new StatsSystem(this);
this.inventorySystem = new InventorySystem(this);
// ========================================================
// 💎 NEOMEJENI VIRI - Les in Kamen
// ========================================================
console.log('💎 Dodajam neomejene vire...');
this.inventorySystem.addItem('wood', 999999);
this.inventorySystem.addItem('stone', 999999);
this.inventorySystem.gold = 999999;
console.log('✅ Neomejeni viri dodani: 999,999 lesa, kamna in zlata!');
// ========================================================
this.lootSystem = new LootSystem(this);
this.interactionSystem = new InteractionSystem(this);
this.farmingSystem = new FarmingSystem(this);
@@ -502,6 +682,7 @@ class GameScene extends Phaser.Scene {
if (this.player) this.player.update(delta);
// Update Systems
if (this.terrainSystem) this.terrainSystem.update(time, delta); // Water animation!
if (this.statsSystem) this.statsSystem.update(delta);
if (this.lootSystem) this.lootSystem.update(delta);
if (this.interactionSystem) this.interactionSystem.update(delta);

View File

@@ -78,23 +78,13 @@ class BuildSystem {
this.buildMode = !this.buildMode;
console.log(`Build Mode: ${this.buildMode ? 'ON' : 'OFF'}`);
// Show tutorial on first time
if (this.buildMode && !this.tutorialShown) {
this.showTutorial();
this.tutorialShown = true;
}
// Notify UI
const uiScene = this.scene.scene.get('UIScene');
if (uiScene) {
uiScene.toggleBuildMenu(this.buildMode);
}
// Show/hide preview
if (this.buildMode) {
this.createPreview();
this.showBuildUI(); // Dodaj UI
} else {
this.destroyPreview();
this.hideBuildUI(); // Skrij UI
}
return this.buildMode;
@@ -104,16 +94,126 @@ class BuildSystem {
if (!this.buildings[buildingId]) return;
this.selectedBuilding = buildingId;
// Update UI
const uiScene = this.scene.scene.get('UIScene');
if (uiScene) {
uiScene.updateBuildSelection(this.buildings[buildingId].name);
}
// Refresh preview
if (this.buildMode) {
this.destroyPreview();
this.createPreview();
this.updateBuildUI(); // Posodobi UI
}
}
showBuildUI() {
const uiScene = this.scene.scene.get('UIScene');
if (!uiScene) return;
const width = this.scene.cameras.main.width;
const height = this.scene.cameras.main.height;
// Ustvari UI container
this.buildUIContainer = uiScene.add.container(width - 250, 100);
this.buildUIContainer.setDepth(9999);
this.buildUIContainer.setScrollFactor(0);
// Ozadje panela
const bg = uiScene.add.rectangle(0, 0, 220, 400, 0x1a1a2e, 0.95);
bg.setStrokeStyle(3, 0x00ff41);
this.buildUIContainer.add(bg);
// Naslov
const title = uiScene.add.text(0, -180, '🏗️ BUILD MODE', {
fontSize: '20px',
fontFamily: 'Courier New',
color: '#00ff41',
fontStyle: 'bold'
}).setOrigin(0.5);
this.buildUIContainer.add(title);
// Izbrana stavba
this.selectedBuildingText = uiScene.add.text(0, -150, '', {
fontSize: '14px',
fontFamily: 'Courier New',
color: '#ffffff',
align: 'center'
}).setOrigin(0.5);
this.buildUIContainer.add(this.selectedBuildingText);
// Cena
this.costText = uiScene.add.text(0, -120, '', {
fontSize: '12px',
fontFamily: 'Courier New',
color: '#ffaa00',
align: 'center'
}).setOrigin(0.5);
this.buildUIContainer.add(this.costText);
// Kontrole
const controls = [
'━━━━━━━━━━━━━━',
'CONTROLS:',
'',
'1 - Fence Post',
'2 - Fence →',
'3 - Fence ↓',
'4 - Fence ⌞',
'5 - Barn',
'',
'Click - Place',
'B - Exit',
'━━━━━━━━━━━━━━'
];
const controlsText = uiScene.add.text(0, 0, controls.join('\n'), {
fontSize: '12px',
fontFamily: 'Courier New',
color: '#aaaaaa',
align: 'center',
lineSpacing: 4
}).setOrigin(0.5);
this.buildUIContainer.add(controlsText);
// Status
this.statusText = uiScene.add.text(0, 170, '', {
fontSize: '11px',
fontFamily: 'Courier New',
color: '#ffffff',
align: 'center'
}).setOrigin(0.5);
this.buildUIContainer.add(this.statusText);
this.updateBuildUI();
}
updateBuildUI() {
if (!this.buildUIContainer) return;
const building = this.buildings[this.selectedBuilding];
// Posodobi ime
this.selectedBuildingText.setText(`Selected:\n${building.name}`);
// Posodobi ceno
let costStr = 'Cost: ';
const costs = [];
for (const [resource, amount] of Object.entries(building.cost)) {
if (resource === 'gold') {
costs.push(`${amount} Gold`);
} else {
costs.push(`${amount} ${resource}`);
}
}
costStr += costs.join(', ');
this.costText.setText(costStr);
// Preveri vire
const hasResources = this.hasResources(building.cost);
this.statusText.setText(hasResources ? '✅ Ready to build' : '❌ Not enough resources');
this.statusText.setColor(hasResources ? '#00ff41' : '#ff0000');
}
hideBuildUI() {
if (this.buildUIContainer) {
this.buildUIContainer.destroy();
this.buildUIContainer = null;
}
}
@@ -230,6 +330,146 @@ class BuildSystem {
return building ? building.collision : false;
}
/**
* Ročno postavi ograjo na natančno koordinato.
* @param {number} tileX - X koordinata ploščice (0 do 99).
* @param {number} tileY - Y koordinata ploščice (0 do 99).
* @param {string} fenceType - Tip ograje: 'fence', 'fence_post', 'fence_horizontal', 'fence_vertical', 'fence_corner'
* @param {boolean} consumeResources - Ali naj porabi vire (privzeto: false)
* @returns {boolean} - True če je bila ograja uspešno postavljena
*/
placeSingleFence(tileX, tileY, fenceType = 'fence_horizontal', consumeResources = false) {
// 1. Preveri, ali je lokacija znotraj mape
if (tileX < 0 || tileX >= 100 || tileY < 0 || tileY >= 100) {
console.error(`❌ Poskus postavitve ograje izven robov mape: (${tileX}, ${tileY})`);
return false;
}
// 2. Preveri, ali tip ograje obstaja
if (!this.buildings[fenceType]) {
console.error(`❌ Neznan tip ograje: ${fenceType}`);
return false;
}
// 3. Preveri, ali že obstaja zgradba na tej lokaciji
const exists = this.placedBuildings.find(b => b.gridX === tileX && b.gridY === tileY);
if (exists) {
console.warn(`⚠️ Na lokaciji (${tileX}, ${tileY}) že obstaja zgradba.`);
return false;
}
const building = this.buildings[fenceType];
// 4. Preveri in porabi vire (če je zahtevano)
if (consumeResources) {
if (!this.hasResources(building.cost)) {
console.warn(`⚠️ Ni dovolj virov za postavitev ${building.name}`);
return false;
}
const inv = this.scene.inventorySystem;
for (const [resource, amount] of Object.entries(building.cost)) {
if (resource === 'gold') {
inv.gold -= amount;
} else {
inv.removeItem(resource, amount);
}
}
}
// 5. Ustvari sprite
const screenPos = this.scene.iso.toScreen(tileX, tileY);
const sprite = this.scene.add.sprite(screenPos.x, screenPos.y, building.textureKey);
sprite.setOrigin(0.5, 1);
sprite.setScale(building.scale || 1.0);
sprite.setDepth(this.scene.iso.getDepth(tileX, tileY) + 5); // Nad terenom
// 6. Shrani
this.placedBuildings.push({
gridX: tileX,
gridY: tileY,
type: fenceType,
sprite,
collision: building.collision
});
console.log(`${building.name} postavljena na (${tileX}, ${tileY})`);
// 7. Posodobi UI (če so bili porabljeni viri)
if (consumeResources) {
this.scene.events.emit('update-inventory');
}
return true;
}
/**
* Postavi linijo ograj med dvema točkama.
* @param {number} startX - Začetna X koordinata
* @param {number} startY - Začetna Y koordinata
* @param {number} endX - Končna X koordinata
* @param {number} endY - Končna Y koordinata
* @param {string} fenceType - Tip ograje
* @param {boolean} consumeResources - Ali naj porabi vire
*/
placeFenceLine(startX, startY, endX, endY, fenceType = 'fence_horizontal', consumeResources = false) {
const dx = Math.abs(endX - startX);
const dy = Math.abs(endY - startY);
const sx = startX < endX ? 1 : -1;
const sy = startY < endY ? 1 : -1;
let err = dx - dy;
let x = startX;
let y = startY;
while (true) {
this.placeSingleFence(x, y, fenceType, consumeResources);
if (x === endX && y === endY) break;
const e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
x += sx;
}
if (e2 < dx) {
err += dx;
y += sy;
}
}
console.log(`🔗 Linija ograj postavljena od (${startX}, ${startY}) do (${endX}, ${endY})`);
}
/**
* Postavi pravokotnik ograj.
* @param {number} x - Levi zgornji X
* @param {number} y - Levi zgornji Y
* @param {number} width - Širina
* @param {number} height - Višina
* @param {string} fenceType - Tip ograje
* @param {boolean} consumeResources - Ali naj porabi vire
*/
placeFenceRectangle(x, y, width, height, fenceType = 'fence_horizontal', consumeResources = false) {
// Zgornja linija
for (let i = 0; i < width; i++) {
this.placeSingleFence(x + i, y, fenceType, consumeResources);
}
// Spodnja linija
for (let i = 0; i < width; i++) {
this.placeSingleFence(x + i, y + height - 1, fenceType, consumeResources);
}
// Leva linija
for (let i = 1; i < height - 1; i++) {
this.placeSingleFence(x, y + i, fenceType, consumeResources);
}
// Desna linija
for (let i = 1; i < height - 1; i++) {
this.placeSingleFence(x + width - 1, y + i, fenceType, consumeResources);
}
console.log(`📦 Pravokotnik ograj postavljen na (${x}, ${y}) velikosti ${width}x${height}`);
}
showTutorial() {
const uiScene = this.scene.scene.get('UIScene');
if (!uiScene) return;

View File

@@ -81,14 +81,9 @@ class SaveSystem {
}
loadGame() {
console.log('📂 Loading game...');
let rawData = localStorage.getItem(this.storageKey);
if (!rawData) {
console.log('⚠️ No save file found.');
this.showNotification('NO SAVE FOUND');
return false;
}
console.log('📂 Loading game... DISABLED - Fresh start!');
// ONEMOGOČENO - vedno vrne false za fresh start
return false;
try {
let jsonString = rawData;

View File

@@ -16,7 +16,7 @@ const ABANDONED_HOUSES = [
// ========================================================
// GOZD KONSTANTE - STARDEW VALLEY STYLE (OPTIMIZIRANO)
// ========================================================
const TREE_DENSITY = 0.01; // 1% chance za drevo (zelo nizka gostota)
const TREE_DENSITY = 0.0; // 0% - BREZ DREVES!
const PURPLE_TREE_CHANCE = 0.30; // 30% vijolčnih dreves
const FRUIT_TREE_CHANCE = 0.20; // 20% sadnih dreves
const ROCK_DENSITY_THRESHOLD = 0.60; // Prag za skupine skal
@@ -29,6 +29,13 @@ const TILE_MINE_WALL = 81; // ID za zid rudnika
const TILE_STONE_ORE = 82; // ID za navadni kamen
const TILE_IRON_ORE = 83; // ID za železovo rudo
// ========================================================
// RIBNIK KONSTANTE
// ========================================================
const POND_CENTER_X = 30; // Center ribnika
const POND_CENTER_Y = 30; // Center ribnika
const POND_RADIUS = 4; // Radij ribnika (8x8)
// Terrain Generator System
class TerrainSystem {
constructor(scene, width = 100, height = 100) {
@@ -53,6 +60,10 @@ class TerrainSystem {
this.waterTiles = []; // Array za water tiles
this.waterAnimationTimer = 0;
// Rain particles za ribnik
this.rainEmitter = null;
this.splashEmitters = []; // Array splash emitterjev
this.tilePool = {
active: [],
inactive: [],
@@ -168,6 +179,32 @@ class TerrainSystem {
const types = Object.values(this.terrainTypes);
// POSEBNA OBDELAVA ZA VODO - 2D Stardew Valley Style!
if (!this.scene.textures.exists('water')) {
const waterGraphics = this.scene.make.graphics({ x: 0, y: 0, add: false });
// TEMNA MODRA VODA - dobro vidna!
waterGraphics.fillGradientStyle(
0x0a3d62, 0x0a3d62, // Temno modra (zgoraj)
0x1e5f8c, 0x1e5f8c // Srednje modra (spodaj)
);
waterGraphics.fillRect(0, 0, 48, 48);
// Svetli highlights za valovanje
waterGraphics.fillStyle(0x3a8fc2, 0.5);
waterGraphics.fillCircle(12, 12, 10);
waterGraphics.fillCircle(36, 28, 8);
waterGraphics.fillCircle(24, 38, 6);
// Temnejši border za kontrast
waterGraphics.lineStyle(2, 0x062a40, 1);
waterGraphics.strokeRect(0, 0, 48, 48);
waterGraphics.generateTexture('water', 48, 48);
waterGraphics.destroy();
console.log('🌊 2D Water texture created (Stardew Valley style)!');
}
types.forEach((type) => {
if (this.scene.textures.exists(type.name)) return;
@@ -355,6 +392,7 @@ class TerrainSystem {
generate() {
this.createTileTextures();
this.createWaterFrames(); // Ustvari water animation frames!
console.log('🌍 Initializing World (Zone Streaming Mode)...');
@@ -421,6 +459,15 @@ class TerrainSystem {
}
});
// RIBNIK - okrogel ribnik z vodo!
const distToPond = Math.sqrt(
Math.pow(x - POND_CENTER_X, 2) +
Math.pow(y - POND_CENTER_Y, 2)
);
if (distToPond <= POND_RADIUS) {
terrainType = this.terrainTypes.WATER; // Voda!
}
// Create Tile Data
this.tiles[y][x] = {
type: terrainType.name,
@@ -563,8 +610,45 @@ class TerrainSystem {
init(offsetX, offsetY) {
this.offsetX = offsetX;
this.offsetY = offsetY;
// Ustvari rain particles nad ribnikom
this.createRainOnPond();
}
createRainOnPond() {
// Izračunaj screen pozicijo ribnika
const pondScreenPos = this.iso.toScreen(POND_CENTER_X, POND_CENTER_Y);
const pondX = pondScreenPos.x + this.offsetX;
const pondY = pondScreenPos.y + this.offsetY;
// Ustvari particle texture (modra kapljica)
const graphics = this.scene.make.graphics({ x: 0, y: 0, add: false });
graphics.fillStyle(0x4488ff, 1);
graphics.fillCircle(2, 2, 2);
graphics.generateTexture('raindrop', 4, 4);
graphics.destroy();
// Rain emitter - pada v ribnik
this.rainEmitter = this.scene.add.particles(pondX, pondY - 100, 'raindrop', {
x: { min: -50, max: 50 },
y: 0,
lifespan: 1000,
speedY: { min: 200, max: 300 },
scale: { start: 0.5, end: 0.2 },
alpha: { start: 0.8, end: 0.3 },
frequency: 100,
blendMode: 'ADD'
});
// Dodaj rain sound effect
if (this.scene.soundManager) {
this.scene.soundManager.playRainSound();
}
console.log('🌧️ Rain particles created over pond!');
}
setTile(x, y, type) {
if (x >= 0 && x < this.width && y >= 0 && y < this.height) {
this.tiles[y][x].type = type;
@@ -887,15 +971,17 @@ class TerrainSystem {
// Use water texture with animation support
if (tile.type === 'water') {
// Check if water frames exist
if (this.scene.textures.exists('water_frame_0')) {
sprite.setTexture('water_frame_0');
// Mark sprite for animation
sprite.isWater = true;
sprite.waterFrame = 0;
} else {
sprite.setTexture('water');
}
sprite.setTexture('water');
// ANIMACIJA: Dodaj alpha tween za valovanje
this.scene.tweens.add({
targets: sprite,
alpha: 0.7,
duration: 1000,
yoyo: true,
repeat: -1,
ease: 'Sine.easeInOut'
});
} else {
sprite.setTexture(tile.type);
}
@@ -1086,43 +1172,9 @@ class TerrainSystem {
return true; // Out of bounds = solid
}
// Water Animation Update
// Water Animation Update - DISABLED (using tweens now)
update(time, delta) {
// Posodobi water animation timer
this.waterAnimationTimer += delta;
// Water frame animacija (vsake 150ms = ~6.6 FPS za smooth flow)
if (this.waterAnimationTimer > 150) {
this.waterAnimationTimer = 0;
// Increment frame counter
if (!this.waterCurrentFrame) this.waterCurrentFrame = 0;
this.waterCurrentFrame = (this.waterCurrentFrame + 1) % 4; // Cycle 0-3
// DEBUG
let waterTileCount = 0;
// Update vse visible water tiles s novim frame-om
this.visibleTiles.forEach((sprite, key) => {
const coords = key.split(',');
const x = parseInt(coords[0]);
const y = parseInt(coords[1]);
if (this.tiles[y] && this.tiles[y][x] && this.tiles[y][x].type === 'water') {
sprite.setTexture(`water_frame_${this.waterCurrentFrame}`);
waterTileCount++;
}
});
// DEBUG LOG
if (waterTileCount > 0) {
console.log(`🌊 Water animation: frame ${this.waterCurrentFrame} updated ${waterTileCount} tiles`);
} else {
console.warn('⚠️ No water tiles found in visibleTiles!', {
visibleTilesCount: this.visibleTiles.size,
currentFrame: this.waterCurrentFrame
});
}
}
// Water animation je zdaj implementirana z Phaser tweens
// Ni potrebe po ročnem frame update-u
}
}