udomacenje zombija in uboj\

This commit is contained in:
2025-12-07 12:47:47 +01:00
parent 8e401a9d6f
commit 2404d44ef7
10 changed files with 1086 additions and 532 deletions

View File

@@ -6,6 +6,13 @@ class GameScene extends Phaser.Scene {
this.terrainContainer = null;
this.player = null;
this.npcs = []; // Array za NPCje
// Settings
this.settings = {
viewDistance: 'HIGH', // LOW, MEDIUM, HIGH
particles: 'HIGH', // NONE, LOW, HIGH
shadows: true
};
}
create() {
@@ -108,6 +115,9 @@ class GameScene extends Phaser.Scene {
console.log('🌄 Initializing Parallax System...');
this.parallaxSystem = new ParallaxSystem(this);
// Generate Item Sprites for UI
TextureGenerator.createItemSprites(this);
// Launch UI Scene
console.log('🖥️ Launching UI Scene...');
this.scene.launch('UIScene');
@@ -115,10 +125,10 @@ class GameScene extends Phaser.Scene {
// Initialize Save System
this.saveSystem = new SaveSystem(this);
// Auto-load if available (optional, for now manual)
// this.saveSystem.loadGame();
// Auto-load if available
this.saveSystem.loadGame();
console.log('✅ GameScene ready - FAZA 17!');
console.log('✅ GameScene ready - FAZA 18 (Crafting & AI)!');
}
setupCamera() {
@@ -277,4 +287,12 @@ class GameScene extends Phaser.Scene {
this.clouds.push({ sprite: cloud, speed: Phaser.Math.FloatBetween(10, 30) });
}
}
saveGame() {
if (this.saveSystem) this.saveSystem.saveGame();
}
loadGame() {
if (this.saveSystem) this.saveSystem.loadGame();
}
}

View File

@@ -20,9 +20,121 @@ class UIScene extends Phaser.Scene {
this.createGoldDisplay();
this.createClock();
this.createDebugInfo();
this.createSettingsButton();
// Resize event
this.scale.on('resize', this.resize, this);
// Crafting Menu (C)
this.input.keyboard.on('keydown-C', () => {
this.toggleCraftingMenu();
});
// Save (F5)
this.input.keyboard.on('keydown-F5', () => {
if (this.gameScene) this.gameScene.saveGame();
});
// Factory Reset (F8) - Fix za "zginla drevesa"
this.input.keyboard.on('keydown-F8', () => {
console.log('🔥 FACTORY RESET - Clearing Save & Reloading...');
localStorage.removeItem('novafarma_savefile');
window.location.reload();
});
}
// ... (rest of class) ...
toggleCraftingMenu() {
if (!this.craftingContainer) this.createCraftingMenu();
this.craftingContainer.setVisible(!this.craftingContainer.visible);
}
createCraftingMenu() {
const w = 300;
const h = 250;
const x = this.scale.width / 2;
const y = this.scale.height / 2;
this.craftingContainer = this.add.container(x, y);
this.craftingContainer.setDepth(2000); // Top of everything
// Bg
const bg = this.add.graphics();
bg.fillStyle(0x222222, 0.95);
bg.fillRect(-w / 2, -h / 2, w, h);
bg.lineStyle(2, 0x888888, 1);
bg.strokeRect(-w / 2, -h / 2, w, h);
this.craftingContainer.add(bg);
// Title
const title = this.add.text(0, -h / 2 + 20, 'CRAFTING', { fontSize: '24px', fontStyle: 'bold', color: '#ffffff' }).setOrigin(0.5);
this.craftingContainer.add(title);
// Recipes
const recipes = [
{ name: 'Axe', code: '1', req: '5 Wood', type: 'axe', cost: { wood: 5 } },
{ name: 'Pickaxe', code: '2', req: '5 Wood, 2 Stone', type: 'pickaxe', cost: { wood: 5, stone: 2 } },
{ name: 'Hoe', code: '3', req: '3 Wood, 2 Stone', type: 'hoe', cost: { wood: 3, stone: 2 } },
{ name: 'Sword', code: '4', req: '10 Wood, 5 Stone', type: 'sword', cost: { wood: 10, stone: 5 } }
];
recipes.forEach((r, i) => {
const rowY = -h / 2 + 70 + (i * 40);
// Text
const txt = this.add.text(-w / 2 + 20, rowY, `[${r.code}] ${r.name} (${r.req})`, {
fontSize: '16px', color: '#eeeeee'
});
this.craftingContainer.add(txt);
// Button Logic (Keyboard 1-4 works too via GameScene? No, let's localize input)
});
// Instruction
const instr = this.add.text(0, h / 2 - 20, 'Press number keys to craft', { fontSize: '12px', color: '#aaaaaa' }).setOrigin(0.5);
this.craftingContainer.add(instr);
// Input listener for crafting
this.input.keyboard.on('keydown', (e) => {
if (!this.craftingContainer.visible) return;
const key = e.key;
const recipe = recipes.find(r => r.code === key);
if (recipe) {
this.tryCraft(recipe);
}
});
this.craftingContainer.setVisible(false);
}
tryCraft(recipe) {
if (!this.gameScene || !this.gameScene.inventorySystem) return;
const inv = this.gameScene.inventorySystem;
// Check cost
if (recipe.cost.wood && !inv.hasItem('wood', recipe.cost.wood)) {
console.log('Craft fail: Wood');
return; // Add UI feedback "Need Wood"
}
if (recipe.cost.stone && !inv.hasItem('stone', recipe.cost.stone)) {
console.log('Craft fail: Stone');
return;
}
// Consume
if (recipe.cost.wood) inv.removeItem('wood', recipe.cost.wood);
if (recipe.cost.stone) inv.removeItem('stone', recipe.cost.stone);
// Add Item
inv.addItem(recipe.type, 1);
console.log(`Crafted ${recipe.name}!`);
// Flash effect
this.cameras.main.flash(200, 0, 255, 0); // Green flash
this.craftingContainer.setVisible(false);
}
resize(gameSize) {
@@ -35,7 +147,9 @@ class UIScene extends Phaser.Scene {
this.createClock();
this.createGoldDisplay();
this.createInventoryBar();
this.createInventoryBar();
this.createDebugInfo();
this.createSettingsButton();
// Refresh data
if (this.gameScene) {
@@ -539,4 +653,113 @@ class UIScene extends Phaser.Scene {
this.tradeItemsContainer.add(btnBg);
this.tradeItemsContainer.add(btnLabel);
}
// --- SETTINGS MENU ---
createSettingsButton() {
if (this.settingsBtn) this.settingsBtn.destroy();
this.settingsBtn = this.add.text(10, 10, '⚙️ SETTINGS', {
fontSize: '16px',
fill: '#ffffff',
backgroundColor: '#000000',
padding: { x: 5, y: 5 }
});
this.settingsBtn.setInteractive({ useHandCursor: true });
this.settingsBtn.on('pointerdown', () => this.toggleSettingsMenu());
}
toggleSettingsMenu() {
if (!this.settingsContainer) {
this.createSettingsMenu();
}
this.settingsContainer.setVisible(!this.settingsContainer.visible);
if (this.settingsContainer.visible) {
this.settingsContainer.setDepth(20000); // Always on top
}
}
createSettingsMenu() {
this.settingsContainer = this.add.container(this.width / 2, this.height / 2);
// BG
const bg = this.add.graphics();
bg.fillStyle(0x000000, 0.9);
bg.fillRect(-150, -120, 300, 240);
bg.lineStyle(2, 0x888888, 1);
bg.strokeRect(-150, -120, 300, 240);
this.settingsContainer.add(bg);
// Title
const title = this.add.text(0, -90, 'SETTINGS', { fontSize: '24px', fontStyle: 'bold', fill: '#ffffff' }).setOrigin(0.5);
this.settingsContainer.add(title);
// Close
const closeBtn = this.add.text(130, -110, 'X', { fontSize: '20px', fill: '#ff0000' }).setOrigin(0.5);
closeBtn.setInteractive({ useHandCursor: true });
closeBtn.on('pointerdown', () => this.toggleSettingsMenu());
this.settingsContainer.add(closeBtn);
// Options
let y = -40;
// 1. View Distance (Simple Toggle for now: Low/High)
this.createSettingToggle(0, y, 'VIEW DISTANCE',
() => this.gameScene.settings.viewDistance, // getter
(val) => { // setter
this.gameScene.settings.viewDistance = val;
// Apply immediately? Or next frame.
// TerrainSystem reads it in updateCulling? We need to ensure it does.
if (this.gameScene.terrainSystem) this.gameScene.terrainSystem.lastCullX = -9999; // Force update
},
['LOW', 'HIGH']
);
y += 50;
// 2. Weather Particles
this.createSettingToggle(0, y, 'PARTICLES',
() => this.gameScene.settings.particles,
(val) => {
this.gameScene.settings.particles = val;
// Restart rain if active
if (this.gameScene.weatherSystem && (this.gameScene.weatherSystem.currentWeather === 'rain' || this.gameScene.weatherSystem.currentWeather === 'storm')) {
this.gameScene.weatherSystem.startRain(this.gameScene.weatherSystem.currentWeather === 'storm');
}
},
['NONE', 'LOW', 'HIGH']
);
y += 50;
// 3. Shadows
this.createSettingToggle(0, y, 'SHADOWS',
() => this.gameScene.settings.shadows ? 'ON' : 'OFF',
(val) => {
this.gameScene.settings.shadows = (val === 'ON');
// Trigger redraw? Complex. For now just saves state.
// Maybe reload scene?
},
['ON', 'OFF']
);
}
createSettingToggle(x, y, label, getter, setter, options) {
const labelText = this.add.text(x - 80, y, label, { fontSize: '16px', fill: '#aaaaaa' }).setOrigin(1, 0.5);
this.settingsContainer.add(labelText);
const currentVal = getter();
const valueText = this.add.text(x + 50, y, currentVal, { fontSize: '16px', fill: '#ffffff', fontStyle: 'bold' }).setOrigin(0.5, 0.5);
this.settingsContainer.add(valueText);
// Click to cycle
const hitArea = this.add.rectangle(x + 50, y, 100, 30, 0xffffff, 0.1);
hitArea.setInteractive({ useHandCursor: true });
hitArea.on('pointerdown', () => {
const cur = getter();
let idx = options.indexOf(cur);
idx = (idx + 1) % options.length;
const next = options[idx];
setter(next);
valueText.setText(next);
});
this.settingsContainer.add(hitArea);
}
}