podobi
This commit is contained in:
@@ -345,6 +345,15 @@ class GameScene extends Phaser.Scene {
|
||||
console.log('📊 Initializing FPS Monitor...');
|
||||
this.fpsMonitor = new FPSMonitor(this);
|
||||
|
||||
// Performance Monitor (Advanced)
|
||||
console.log('⚡ Initializing Performance Monitor...');
|
||||
this.performanceMonitor = new PerformanceMonitor(this);
|
||||
|
||||
// NPC Spawner
|
||||
console.log('🧟 Initializing NPC Spawner...');
|
||||
this.npcSpawner = new NPCSpawner(this);
|
||||
this.npcSpawner.spawnInitialNPCs();
|
||||
|
||||
// Easter Egg: Broken Scooter
|
||||
console.log('🛵 Spawning Scooter Easter Egg...');
|
||||
this.vehicles = [];
|
||||
@@ -608,6 +617,14 @@ class GameScene extends Phaser.Scene {
|
||||
}
|
||||
};
|
||||
|
||||
// TESTNA DREVESA IN KAMNI - Za testiranje
|
||||
console.log('🌳 Adding test trees and rocks near player...');
|
||||
this.terrainSystem.addDecoration(52, 50, 'tree_green');
|
||||
this.terrainSystem.addDecoration(48, 50, 'rock');
|
||||
this.terrainSystem.addDecoration(50, 52, 'tree_oak');
|
||||
this.terrainSystem.addDecoration(50, 48, 'rock_large');
|
||||
console.log('✅ Test decorations added at (50±2, 50±2)');
|
||||
|
||||
// Start Engine
|
||||
this.Antigravity_Start();
|
||||
}
|
||||
@@ -796,6 +813,17 @@ class GameScene extends Phaser.Scene {
|
||||
// FPS Monitor Update
|
||||
if (this.fpsMonitor) this.fpsMonitor.update();
|
||||
|
||||
// Performance Monitor Update
|
||||
if (this.performanceMonitor) this.performanceMonitor.update(delta);
|
||||
|
||||
// NPC Spawner Update
|
||||
if (this.npcSpawner) this.npcSpawner.update(delta);
|
||||
|
||||
// Update NPCs
|
||||
for (const npc of this.npcs) {
|
||||
if (npc.update) npc.update(delta);
|
||||
}
|
||||
|
||||
// Debug Info
|
||||
if (this.player) {
|
||||
const playerPos = this.player.getPosition();
|
||||
|
||||
@@ -21,6 +21,7 @@ class UIScene extends Phaser.Scene {
|
||||
this.createGoldDisplay();
|
||||
this.createVirtualJoystick();
|
||||
this.createClock();
|
||||
this.createMinimap(); // NEW: Mini mapa
|
||||
// this.createDebugInfo();
|
||||
this.createSettingsButton();
|
||||
|
||||
@@ -303,7 +304,7 @@ class UIScene extends Phaser.Scene {
|
||||
console.log(`Crafted ${recipe.name}!`);
|
||||
|
||||
// Sound & Visuals
|
||||
if (this.gameScene.soundManager) this.gameScene.soundManager.playSuccess();
|
||||
if (this.gameScene.soundManager) this.gameScene.soundManager.beepPickup();
|
||||
this.cameras.main.flash(200, 255, 255, 255);
|
||||
|
||||
// Refresh UI
|
||||
@@ -756,6 +757,9 @@ class UIScene extends Phaser.Scene {
|
||||
this.updateResourceDisplay('stone', inv.getItemCount('stone'));
|
||||
this.updateResourceDisplay('iron', inv.getItemCount('iron'));
|
||||
}
|
||||
|
||||
// Update Minimap
|
||||
this.updateMinimap();
|
||||
}
|
||||
|
||||
createTimeControlPanel() {
|
||||
@@ -2253,4 +2257,113 @@ class UIScene extends Phaser.Scene {
|
||||
if (this.farmGoldEarnedText) this.farmGoldEarnedText.setText(`Gold Earned: ${stats.goldEarned || 0}g`);
|
||||
if (this.farmDaysText) this.farmDaysText.setText(`Days Farmed: ${stats.daysFarmed || 0}`);
|
||||
}
|
||||
|
||||
createMinimap() {
|
||||
const size = 150; // Minimap size
|
||||
const x = 20;
|
||||
const y = this.scale.height - size - 80; // Above inventory bar
|
||||
|
||||
// Container
|
||||
this.minimapContainer = this.add.container(x, y);
|
||||
this.minimapContainer.setDepth(1000);
|
||||
|
||||
// Background
|
||||
const bg = this.add.graphics();
|
||||
bg.fillStyle(0x000000, 0.7);
|
||||
bg.fillRect(0, 0, size, size);
|
||||
bg.lineStyle(2, 0x00ff41, 0.8);
|
||||
bg.strokeRect(0, 0, size, size);
|
||||
this.minimapContainer.add(bg);
|
||||
|
||||
// Title
|
||||
const title = this.add.text(size / 2, -15, 'MINIMAP', {
|
||||
fontSize: '12px',
|
||||
fontFamily: 'Courier New',
|
||||
fill: '#00ff41',
|
||||
fontStyle: 'bold'
|
||||
}).setOrigin(0.5);
|
||||
this.minimapContainer.add(title);
|
||||
|
||||
// Minimap graphics (will be updated in update())
|
||||
this.minimapGraphics = this.add.graphics();
|
||||
this.minimapGraphics.setPosition(x, y);
|
||||
this.minimapGraphics.setDepth(1001);
|
||||
|
||||
// Player dot
|
||||
this.minimapPlayerDot = this.add.circle(size / 2, size / 2, 3, 0xffff00);
|
||||
this.minimapContainer.add(this.minimapPlayerDot);
|
||||
|
||||
console.log('🗺️ Minimap created!');
|
||||
}
|
||||
|
||||
updateMinimap() {
|
||||
if (!this.minimapGraphics || !this.gameScene || !this.gameScene.player) return;
|
||||
|
||||
const size = 150;
|
||||
const worldSize = 100; // Assuming 100x100 world
|
||||
const scale = size / worldSize;
|
||||
|
||||
this.minimapGraphics.clear();
|
||||
|
||||
// Get player position
|
||||
const player = this.gameScene.player;
|
||||
const playerGridX = Math.floor(player.gridX || 0);
|
||||
const playerGridY = Math.floor(player.gridY || 0);
|
||||
|
||||
// Draw terrain (simplified)
|
||||
if (this.gameScene.terrainSystem && this.gameScene.terrainSystem.tiles) {
|
||||
const viewRange = 20; // Show 20x20 tiles around player
|
||||
const startX = Math.max(0, playerGridX - viewRange);
|
||||
const endX = Math.min(worldSize, playerGridX + viewRange);
|
||||
const startY = Math.max(0, playerGridY - viewRange);
|
||||
const endY = Math.min(worldSize, playerGridY + viewRange);
|
||||
|
||||
for (let gx = startX; gx < endX; gx++) {
|
||||
for (let gy = startY; gy < endY; gy++) {
|
||||
const tile = this.gameScene.terrainSystem.getTile(gx, gy);
|
||||
if (!tile) continue;
|
||||
|
||||
let color = 0x44aa44; // Default green (grass)
|
||||
if (tile.type === 'water') color = 0x0088ff;
|
||||
else if (tile.type === 'sand') color = 0xffdd88;
|
||||
else if (tile.type === 'stone') color = 0x888888;
|
||||
else if (tile.type === 'farm') color = 0x8B4513; // Brown for farm
|
||||
|
||||
const mx = (gx - playerGridX + viewRange) * (size / (viewRange * 2));
|
||||
const my = (gy - playerGridY + viewRange) * (size / (viewRange * 2));
|
||||
|
||||
this.minimapGraphics.fillStyle(color, 0.8);
|
||||
this.minimapGraphics.fillRect(
|
||||
this.minimapContainer.x + mx,
|
||||
this.minimapContainer.y + my,
|
||||
size / (viewRange * 2),
|
||||
size / (viewRange * 2)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw NPCs (red dots)
|
||||
if (this.gameScene.npcs) {
|
||||
this.gameScene.npcs.forEach(npc => {
|
||||
const dx = npc.gridX - playerGridX;
|
||||
const dy = npc.gridY - playerGridY;
|
||||
const viewRange = 20;
|
||||
|
||||
if (Math.abs(dx) < viewRange && Math.abs(dy) < viewRange) {
|
||||
const mx = (dx + viewRange) * (size / (viewRange * 2));
|
||||
const my = (dy + viewRange) * (size / (viewRange * 2));
|
||||
|
||||
const color = npc.isTamed ? 0x00ff00 : 0xff0000; // Green if tamed, red if hostile
|
||||
this.minimapGraphics.fillStyle(color, 1);
|
||||
this.minimapGraphics.fillCircle(
|
||||
this.minimapContainer.x + mx,
|
||||
this.minimapContainer.y + my,
|
||||
2
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,11 @@ class BuildSystem {
|
||||
if (!this.buildings[buildingId]) return;
|
||||
this.selectedBuilding = buildingId;
|
||||
|
||||
// Play UI click sound
|
||||
if (this.scene.soundManager) {
|
||||
this.scene.soundManager.playUIClick();
|
||||
}
|
||||
|
||||
// Refresh preview
|
||||
if (this.buildMode) {
|
||||
this.destroyPreview();
|
||||
@@ -319,6 +324,11 @@ class BuildSystem {
|
||||
collision: building.collision
|
||||
});
|
||||
|
||||
// Play build sound
|
||||
if (this.scene.soundManager) {
|
||||
this.scene.soundManager.playBuild();
|
||||
}
|
||||
|
||||
console.log(`🏗️ Placed ${building.name} at (${gridX}, ${gridY})`);
|
||||
|
||||
// Update UI
|
||||
|
||||
@@ -56,6 +56,11 @@ class FarmingSystem {
|
||||
this.scene.terrainSystem.tilledSprites.set(key, sprite);
|
||||
}
|
||||
|
||||
// Play dig sound
|
||||
if (this.scene.soundManager) {
|
||||
this.scene.soundManager.playDig();
|
||||
}
|
||||
|
||||
console.log(`✅ Tilled soil at (${gridX}, ${gridY})`);
|
||||
return true;
|
||||
}
|
||||
@@ -98,6 +103,11 @@ class FarmingSystem {
|
||||
this.scene.farmStats.cropsPlanted++;
|
||||
}
|
||||
|
||||
// Play plant sound
|
||||
if (this.scene.soundManager) {
|
||||
this.scene.soundManager.playPlant();
|
||||
}
|
||||
|
||||
console.log(`🌱 Planted ${cropType} at (${gridX}, ${gridY})`);
|
||||
return true;
|
||||
}
|
||||
@@ -164,6 +174,11 @@ class FarmingSystem {
|
||||
if (crop.sprite) crop.sprite.destroy();
|
||||
this.crops = this.crops.filter(c => c !== crop);
|
||||
|
||||
// Play harvest sound
|
||||
if (this.scene.soundManager) {
|
||||
this.scene.soundManager.playHarvest();
|
||||
}
|
||||
|
||||
console.log(`🌾 Harvested ${crop.type}! (+${goldEarned} gold)`);
|
||||
|
||||
// Show floating text
|
||||
|
||||
76
src/systems/NPCSpawner.js
Normal file
76
src/systems/NPCSpawner.js
Normal file
@@ -0,0 +1,76 @@
|
||||
// NPCSpawner.js - Sistem za spawnjanje NPCjev
|
||||
class NPCSpawner {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.spawnInterval = 30000; // 30 sekund
|
||||
this.maxNPCs = 3; // 3 NPCji na 100x100 mapo
|
||||
this.spawnTimer = 0;
|
||||
|
||||
console.log('🧑 NPCSpawner: Initialized');
|
||||
}
|
||||
|
||||
spawnInitialNPCs() {
|
||||
// Spawn 3 NPCs at random locations
|
||||
for (let i = 0; i < this.maxNPCs; i++) {
|
||||
this.spawnRandomNPC();
|
||||
}
|
||||
console.log(`✅ Spawned ${this.maxNPCs} initial NPCs`);
|
||||
}
|
||||
|
||||
spawnRandomNPC() {
|
||||
if (!this.scene.terrainSystem || !this.scene.npcs) return;
|
||||
|
||||
// Random position (avoid farm area 20,20)
|
||||
let x, y, attempts = 0;
|
||||
do {
|
||||
x = Phaser.Math.Between(5, 95);
|
||||
y = Phaser.Math.Between(5, 95);
|
||||
attempts++;
|
||||
} while (this.isTooCloseToFarm(x, y) && attempts < 50);
|
||||
|
||||
// Check if tile is valid
|
||||
const tile = this.scene.terrainSystem.getTile(x, y);
|
||||
if (!tile || tile.type === 'water') return;
|
||||
|
||||
// Check if decoration exists
|
||||
const key = `${x},${y}`;
|
||||
if (this.scene.terrainSystem.decorationsMap.has(key)) return;
|
||||
|
||||
// Spawn NPC
|
||||
const npc = new NPC(
|
||||
this.scene,
|
||||
x,
|
||||
y,
|
||||
this.scene.terrainOffsetX || 0,
|
||||
this.scene.terrainOffsetY || 0,
|
||||
'zombie' // Type
|
||||
);
|
||||
|
||||
// Set to PASSIVE mode (random walk)
|
||||
npc.state = 'PASSIVE';
|
||||
npc.isTamed = false;
|
||||
|
||||
this.scene.npcs.push(npc);
|
||||
console.log(`🧟 Spawned NPC at (${x}, ${y})`);
|
||||
}
|
||||
|
||||
isTooCloseToFarm(x, y) {
|
||||
const farmX = 50; // Farm center (updated from 20,20 to 50,50)
|
||||
const farmY = 50;
|
||||
const farmRadius = 15;
|
||||
|
||||
const dist = Math.sqrt((x - farmX) ** 2 + (y - farmY) ** 2);
|
||||
return dist < farmRadius;
|
||||
}
|
||||
|
||||
update(delta) {
|
||||
// Check if we need to spawn more NPCs
|
||||
if (this.scene.npcs.length < this.maxNPCs) {
|
||||
this.spawnTimer += delta;
|
||||
if (this.spawnTimer >= this.spawnInterval) {
|
||||
this.spawnTimer = 0;
|
||||
this.spawnRandomNPC();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -299,7 +299,8 @@ class SoundManager {
|
||||
playHarvest() { this.playSFX('harvest'); }
|
||||
playBuild() { this.playSFX('build'); }
|
||||
playPickup() { this.playSFX('pickup'); }
|
||||
playDig() { this.playSFX('dig'); } // Dodano
|
||||
playDig() { this.playSFX('dig'); }
|
||||
playUIClick() { this.beepUIClick(); } // UI click sound
|
||||
playAttack() { this.beepAttack(); }
|
||||
playHit() { this.beepHit(); }
|
||||
playFootstep() { this.beepFootstep(); }
|
||||
@@ -307,6 +308,22 @@ class SoundManager {
|
||||
playRainSound() { this.startRainNoise(); }
|
||||
stopRainSound() { this.stopRainNoise(); }
|
||||
|
||||
beepUIClick() {
|
||||
if (!this.scene.sound.context) return;
|
||||
const ctx = this.scene.sound.context;
|
||||
const osc = ctx.createOscillator();
|
||||
const gain = ctx.createGain();
|
||||
osc.connect(gain);
|
||||
gain.connect(ctx.destination);
|
||||
// Quick, pleasant click sound
|
||||
osc.frequency.value = 800;
|
||||
osc.type = 'sine';
|
||||
gain.gain.setValueAtTime(0.08, ctx.currentTime);
|
||||
gain.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.05);
|
||||
osc.start();
|
||||
osc.stop(ctx.currentTime + 0.05);
|
||||
}
|
||||
|
||||
beepDig() {
|
||||
if (!this.scene.sound.context) return;
|
||||
const ctx = this.scene.sound.context;
|
||||
|
||||
@@ -833,8 +833,9 @@ class TerrainSystem {
|
||||
const isSolid = !isSmallDecor && (
|
||||
typeLower.includes('tree') ||
|
||||
typeLower.includes('sapling') ||
|
||||
typeLower.includes('rock') ||
|
||||
typeLower.includes('stone') ||
|
||||
// ROCKS REMOVED - walkable now!
|
||||
// typeLower.includes('rock') ||
|
||||
// typeLower.includes('stone') ||
|
||||
// fence REMOVED - it's walkable now!
|
||||
typeLower.includes('wall') ||
|
||||
typeLower.includes('signpost') ||
|
||||
|
||||
Reference in New Issue
Block a user