test
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user