posodobitve

This commit is contained in:
2025-12-12 13:40:51 +01:00
parent a210638002
commit 6c583a6576
32 changed files with 6586 additions and 703 deletions

View File

@@ -464,6 +464,21 @@ class GameScene extends Phaser.Scene {
this.particleEffects = new ParticleEffects(this);
this.particleEffects.createFallingLeaves();
// Initialize Accessibility System
console.log('♿ Initializing Accessibility System...');
this.accessibilitySystem = new AccessibilitySystem(this);
// Show epilepsy warning on first launch
const hasSeenWarning = localStorage.getItem('novafarma_epilepsy_warning');
if (!hasSeenWarning) {
this.time.delayedCall(2000, () => {
this.accessibilitySystem.showEpilepsyWarning(() => {
localStorage.setItem('novafarma_epilepsy_warning', 'true');
});
});
}
// Generate Item Sprites for UI
TextureGenerator.createItemSprites(this);

View File

@@ -375,72 +375,79 @@ class PreloadScene extends Phaser.Scene {
const width = this.cameras.main.width;
const height = this.cameras.main.height;
// Background for loading screen
// Warm background (Stardew Valley style)
const bg = this.add.graphics();
bg.fillStyle(0x000000, 1);
bg.fillStyle(0x2d1b00, 1);
bg.fillRect(0, 0, width, height);
// Styling
const primaryColor = 0x00ff41; // Matrix Green
const secondaryColor = 0xffffff;
// Logo / Title
const title = this.add.text(width / 2, height / 2 - 80, 'NOVA FARMA', {
fontFamily: 'Courier New', fontSize: '32px', fontStyle: 'bold', fill: '#00cc00'
// Simple "LOADING" text
const title = this.add.text(width / 2, height / 2 - 80, 'LOADING', {
fontFamily: 'Georgia, serif',
fontSize: '36px',
fontStyle: 'bold',
fill: '#f4e4c1',
stroke: '#2d1b00',
strokeThickness: 4
}).setOrigin(0.5);
const tipText = this.add.text(width / 2, height - 50, 'Tip: Zombies drop blueprints for new tech...', {
fontFamily: 'monospace', fontSize: '14px', fill: '#888888', fontStyle: 'italic'
}).setOrigin(0.5);
// Progress Bar container (wooden style)
const barWidth = 400;
const barHeight = 30;
const barX = width / 2 - barWidth / 2;
const barY = height / 2;
// Progress Bar container
const progressBox = this.add.graphics();
progressBox.fillStyle(0x111111, 0.8);
progressBox.fillRoundedRect(width / 2 - 160, height / 2 - 15, 320, 30, 5);
progressBox.lineStyle(2, 0x333333, 1);
progressBox.strokeRoundedRect(width / 2 - 160, height / 2 - 15, 320, 30, 5);
progressBox.fillStyle(0x4a3520, 0.9);
progressBox.fillRoundedRect(barX, barY, barWidth, barHeight, 5);
progressBox.lineStyle(3, 0xd4a574, 1);
progressBox.strokeRoundedRect(barX, barY, barWidth, barHeight, 5);
const progressBar = this.add.graphics();
const percentText = this.add.text(width / 2, height / 2, '0%', {
font: '16px Courier New',
fill: '#ffffff',
fontStyle: 'bold'
// Zombie sprite walking on the bar
const zombie = this.add.text(barX, barY + barHeight / 2, '🧟', {
fontSize: '32px'
}).setOrigin(0.5);
const assetLoadingText = this.add.text(width / 2, height / 2 + 30, 'Initializing...', {
font: '12px console', fill: '#aaaaaa'
// Percentage text
const percentText = this.add.text(width / 2, barY + barHeight / 2, '0%', {
font: '16px Georgia',
fill: '#f4e4c1',
fontStyle: 'bold'
}).setOrigin(0.5);
this.load.on('progress', (value) => {
percentText.setText(parseInt(value * 100) + '%');
progressBar.clear();
progressBar.fillStyle(primaryColor, 1);
progressBar.fillStyle(0x6b4423, 1);
// Smooth fill
const w = 310 * value;
const w = (barWidth - 10) * value;
if (w > 0) {
progressBar.fillRoundedRect(width / 2 - 155, height / 2 - 10, w, 20, 2);
progressBar.fillRoundedRect(barX + 5, barY + 5, w, barHeight - 10, 2);
}
});
this.load.on('fileprogress', (file) => {
assetLoadingText.setText(`Loading: ${file.key}`);
// Move zombie along the bar (moderate speed)
const zombieX = barX + (barWidth * value);
zombie.setX(zombieX);
// Gentle bounce animation
const bounce = Math.sin(value * 20) * 3;
zombie.setY(barY + barHeight / 2 + bounce);
});
this.load.on('complete', () => {
// Fade out animation
this.tweens.add({
targets: [progressBar, progressBox, percentText, assetLoadingText, title, tipText, bg],
targets: [progressBar, progressBox, percentText, title, zombie, bg],
alpha: 0,
duration: 1000,
duration: 800,
onComplete: () => {
progressBar.destroy();
progressBox.destroy();
percentText.destroy();
assetLoadingText.destroy();
title.destroy();
tipText.destroy();
zombie.destroy();
bg.destroy();
}
});
@@ -451,60 +458,10 @@ class PreloadScene extends Phaser.Scene {
console.log('✅ PreloadScene: Assets loaded!');
window.gameState.currentScene = 'PreloadScene';
const width = this.cameras.main.width;
const height = this.cameras.main.height;
const title = this.add.text(width / 2, height / 2 - 50, 'KRVAVA ŽETEV', {
fontFamily: 'Courier New',
fontSize: '48px',
fill: '#ff0000',
fontStyle: 'bold',
stroke: '#000000',
strokeThickness: 6
});
title.setOrigin(0.5);
const subtitle = this.add.text(width / 2, height / 2 + 10, 'Zombie Roots', {
fontFamily: 'Courier New',
fontSize: '24px',
fill: '#00ff41'
});
subtitle.setOrigin(0.5);
const instruction = this.add.text(width / 2, height / 2 + 60, 'Press SPACE to start', {
fontFamily: 'Courier New',
fontSize: '16px',
fill: '#888888'
});
instruction.setOrigin(0.5);
this.tweens.add({
targets: instruction,
alpha: 0.3,
duration: 800,
yoyo: true,
repeat: -1
});
const startGame = () => {
// Go directly to main menu (StoryScene)
this.time.delayedCall(500, () => {
console.log('🎮 Starting StoryScene...');
this.input.keyboard.off('keydown');
this.input.off('pointerdown');
this.scene.start('StoryScene');
};
this.time.delayedCall(3000, () => {
startGame();
});
this.input.keyboard.on('keydown', (event) => {
if (event.code === 'Space' || event.code === 'Enter') {
startGame();
}
});
this.input.on('pointerdown', () => {
startGame();
});
}

View File

@@ -7,107 +7,61 @@ class StoryScene extends Phaser.Scene {
const width = this.cameras.main.width;
const height = this.cameras.main.height;
// Dark background with gradient
const bg = this.add.rectangle(0, 0, width, height, 0x0a0a0a);
// Warm background (Stardew Valley style)
const bg = this.add.rectangle(0, 0, width, height, 0x2d1b00);
bg.setOrigin(0);
// GLOW EFFECT for title (multiple Text objects)
const titleGlow1 = this.add.text(width / 2, 80, 'NOVAFARMA', {
fontSize: '72px',
fontFamily: 'Courier New',
color: '#00ff41',
fontStyle: 'bold'
});
titleGlow1.setOrigin(0.5);
titleGlow1.setAlpha(0.3);
titleGlow1.setScale(1.05);
// Add subtle texture overlay
const overlay = this.add.rectangle(0, 0, width, height, 0x000000, 0.3);
overlay.setOrigin(0);
const titleGlow2 = this.add.text(width / 2, 80, 'NOVAFARMA', {
fontSize: '72px',
fontFamily: 'Courier New',
color: '#00ff41',
fontStyle: 'bold'
});
titleGlow2.setOrigin(0.5);
titleGlow2.setAlpha(0.5);
titleGlow2.setScale(1.02);
// MAIN TITLE (horizontal, top center)
const titleBg = this.add.rectangle(width / 2, 80, 480, 70, 0x4a3520, 0.9);
titleBg.setStrokeStyle(3, 0xd4a574);
// Main title
const title = this.add.text(width / 2, 80, 'NOVAFARMA', {
fontSize: '72px',
fontFamily: 'Courier New',
color: '#00ff41',
fontSize: '42px',
fontFamily: 'Georgia, serif',
color: '#f4e4c1',
fontStyle: 'bold',
stroke: '#003311',
strokeThickness: 8
stroke: '#2d1b00',
strokeThickness: 4
});
title.setOrigin(0.5);
// Pulsing glow animation
this.tweens.add({
targets: [titleGlow1, titleGlow2],
scaleX: 1.08,
scaleY: 1.08,
alpha: 0.6,
duration: 2000,
yoyo: true,
repeat: -1,
ease: 'Sine.easeInOut'
});
// Subtle title bounce
// Subtle glow
this.tweens.add({
targets: title,
y: 75,
duration: 3000,
alpha: 0.9,
yoyo: true,
repeat: -1,
duration: 2000,
ease: 'Sine.easeInOut'
});
// Subtitle
const subtitle = this.add.text(width / 2, 150, '2084 - Survival Farm', {
fontSize: '20px',
fontFamily: 'Courier New',
color: '#888888'
const subtitle = this.add.text(width / 2, 120, '~ 2084 - Survival Farm ~', {
fontSize: '14px',
fontFamily: 'Georgia, serif',
color: '#d4a574',
fontStyle: 'italic'
});
subtitle.setOrigin(0.5);
// Accessibility Info Panel (Prominent)
const accessibilityInfo = this.add.text(width / 2, 190,
'♿ ACCESSIBILITY OPTIONS AVAILABLE BELOW ↓\nFor players with visual, motor, or cognitive needs',
{
fontSize: '14px',
fontFamily: 'Courier New',
color: '#44ff44',
align: 'center',
backgroundColor: '#1a1a2e',
padding: { x: 15, y: 8 }
}
);
accessibilityInfo.setOrigin(0.5);
// Pulsing animation for visibility
this.tweens.add({
targets: accessibilityInfo,
alpha: 0.7,
yoyo: true,
repeat: -1,
duration: 1500,
ease: 'Sine.easeInOut'
});
// Main Menu Buttons
// Main Menu Buttons (center)
this.createMainMenu(width, height);
// Language selector (bottom)
// Accessibility icon (top-right)
this.createAccessibilityIcon(width, height);
// Language selector with rotating globe (bottom-right)
this.createLanguageSelector(width, height);
// Version info
const version = this.add.text(10, height - 30, 'v0.9.0 ALPHA', {
fontSize: '14px',
color: '#444444',
fontFamily: 'Courier New'
color: '#6b4423',
fontFamily: 'Georgia, serif'
});
}
@@ -115,111 +69,152 @@ class StoryScene extends Phaser.Scene {
const buttons = [
{
label: '▶ NEW GAME',
color: '#00ff41',
action: () => this.startNewGame(),
description: 'Start a new adventure'
color: '#8fbc8f',
action: () => this.startNewGame()
},
{
label: '📁 LOAD GAME',
color: '#4477ff',
action: () => this.loadGame(),
description: 'Continue your saved game'
color: '#87ceeb',
action: () => this.loadGame()
},
{
label: '⚙️ SETTINGS',
color: '#ffaa00',
action: () => this.showSettings(),
description: 'Graphics, audio, controls'
},
{
label: '♿ ACCESSIBILITY',
color: '#44ff44',
action: () => this.showAccessibility(),
description: 'Options for disabilities: Vision, Motor, Cognitive, Epilepsy'
color: '#daa520',
action: () => this.showSettings()
},
{
label: '❌ EXIT',
color: '#ff4444',
action: () => this.exitGame(),
description: 'Close the game'
color: '#cd5c5c',
action: () => this.exitGame()
}
];
const startY = 230;
const spacing = 75;
const startY = 170;
const spacing = 58;
buttons.forEach((btn, index) => {
const y = startY + (index * spacing);
// Button background
const bg = this.add.rectangle(width / 2, y, 400, 60, 0x1a1a2e, 1);
bg.setStrokeStyle(3, 0x00ff41);
// Wooden button background (Stardew style)
const bg = this.add.rectangle(width / 2, y, 280, 48, 0x6b4423, 1);
bg.setStrokeStyle(2, 0xd4a574);
// Inner shadow effect
const innerShadow = this.add.rectangle(width / 2, y + 2, 270, 38, 0x4a3520, 0.5);
// Button text
const text = this.add.text(width / 2, y, btn.label, {
fontSize: '28px',
fontFamily: 'Courier New',
fontSize: '20px',
fontFamily: 'Georgia, serif',
color: btn.color,
fontStyle: 'bold'
fontStyle: 'bold',
stroke: '#2d1b00',
strokeThickness: 3
});
text.setOrigin(0.5);
// Description text (hidden by default)
const desc = this.add.text(width / 2, y + 40, btn.description, {
fontSize: '12px',
fontFamily: 'Courier New',
color: '#888888',
align: 'center'
});
desc.setOrigin(0.5);
desc.setAlpha(0); // Hidden initially
// Make interactive
bg.setInteractive({ useHandCursor: true });
bg.on('pointerover', () => {
bg.setFillStyle(0x2a2a4e);
text.setScale(1.1);
desc.setAlpha(1); // Show description
bg.setFillStyle(0x8b5a3c);
text.setScale(1.05);
bg.setStrokeStyle(4, 0xf4e4c1);
});
bg.on('pointerout', () => {
bg.setFillStyle(0x1a1a2e);
bg.setFillStyle(0x6b4423);
text.setScale(1.0);
desc.setAlpha(0); // Hide description
bg.setStrokeStyle(3, 0xd4a574);
});
bg.on('pointerdown', () => {
// Flash effect
// Press effect
this.tweens.add({
targets: bg,
alpha: 0.5,
yoyo: true,
targets: [bg, text, innerShadow],
y: y + 3,
duration: 100,
yoyo: true,
onComplete: btn.action
});
});
});
}
createAccessibilityIcon(width, height) {
// Accessibility icon (top-right) - Stardew style
const iconBg = this.add.circle(width - 50, 40, 26, 0x6b4423);
iconBg.setStrokeStyle(2, 0xd4a574);
const icon = this.add.text(width - 50, 40, '♿', {
fontSize: '32px',
color: '#8fbc8f'
});
icon.setOrigin(0.5);
icon.setInteractive({ useHandCursor: true });
// Gentle pulse animation
this.tweens.add({
targets: [icon, iconBg],
scale: 1.08,
duration: 1500,
yoyo: true,
repeat: -1,
ease: 'Sine.easeInOut'
});
icon.on('pointerover', () => {
icon.setScale(1.2);
iconBg.setScale(1.2);
iconBg.setFillStyle(0x8b5a3c);
});
icon.on('pointerout', () => {
icon.setScale(1.0);
iconBg.setScale(1.0);
iconBg.setFillStyle(0x6b4423);
});
icon.on('pointerdown', () => {
this.showAccessibility();
});
}
createLanguageSelector(width, height) {
// Initialize localization
if (!window.i18n) {
window.i18n = new LocalizationSystem();
}
// Globe button (bottom-right)
const globeBtn = this.add.text(width - 80, height - 60, '🌍', {
fontSize: '48px'
// Wooden circle background for globe (Stardew style)
const globeBg = this.add.circle(width - 60, height - 60, 30, 0x6b4423);
globeBg.setStrokeStyle(2, 0xd4a574);
// Rotating globe button
const globeBtn = this.add.text(width - 60, height - 60, '🌍', {
fontSize: '42px'
});
globeBtn.setOrigin(0.5);
globeBtn.setInteractive({ useHandCursor: true });
// Continuous rotation animation
this.tweens.add({
targets: globeBtn,
angle: 360,
duration: 8000,
repeat: -1,
ease: 'Linear'
});
let langMenuOpen = false;
let langMenu = null;
globeBtn.on('pointerover', () => {
globeBtn.setScale(1.2);
globeBtn.setScale(1.15);
globeBg.setScale(1.15);
globeBg.setFillStyle(0x8b5a3c);
});
globeBtn.on('pointerout', () => {
if (!langMenuOpen) globeBtn.setScale(1.0);
if (!langMenuOpen) {
globeBtn.setScale(1.0);
globeBg.setScale(1.0);
globeBg.setFillStyle(0x6b4423);
}
});
globeBtn.on('pointerdown', () => {
if (langMenuOpen) {
@@ -245,45 +240,55 @@ class StoryScene extends Phaser.Scene {
const container = this.add.container(0, 0);
const languages = [
{ code: 'slo', flag: '🇸🇮', name: 'SLO' },
{ code: 'en', flag: '🇬🇧', name: 'ENG' },
{ code: 'de', flag: '🇩🇪', name: 'DEU' },
{ code: 'it', flag: '🇮🇹', name: 'ITA' },
{ code: 'slo', flag: '🇸🇮', name: 'Slovenščina' },
{ code: 'en', flag: '🇬🇧', name: 'English' },
{ code: 'de', flag: '🇩🇪', name: 'Deutsch' },
{ code: 'it', flag: '🇮🇹', name: 'Italiano' },
{ code: 'cn', flag: '🇨🇳', name: '中文' }
];
const menuX = width - 220;
const menuX = width - 200;
const menuY = height - 350;
const menuW = 200;
const menuH = 280;
const menuW = 180;
const menuH = 290;
// Panel background
const panel = this.add.rectangle(menuX, menuY, menuW, menuH, 0x1a1a2e, 0.98);
panel.setStrokeStyle(3, 0x00ff41);
// Wooden panel background (Stardew style)
const panel = this.add.rectangle(menuX, menuY, menuW, menuH, 0x6b4423, 0.98);
panel.setStrokeStyle(4, 0xd4a574);
container.add(panel);
// Title
const title = this.add.text(menuX, menuY - 120, 'LANGUAGE', {
fontSize: '18px',
fontFamily: 'Georgia, serif',
color: '#f4e4c1',
fontStyle: 'bold'
});
title.setOrigin(0.5);
container.add(title);
// Language buttons
languages.forEach((lang, index) => {
const btnY = menuY - 100 + (index * 55);
const btnY = menuY - 90 + (index * 56);
const isActive = window.i18n.getCurrentLanguage() === lang.code;
const btn = this.add.text(menuX, btnY, `${lang.flag} ${lang.name}`, {
fontSize: '20px',
fontFamily: 'Courier New',
color: isActive ? '#00ff41' : '#ffffff',
backgroundColor: isActive ? '#333333' : '#1a1a2e',
padding: { x: 15, y: 8 }
fontSize: '16px',
fontFamily: 'Georgia, serif',
color: isActive ? '#8fbc8f' : '#f4e4c1',
backgroundColor: isActive ? '#4a3520' : '#6b4423',
padding: { x: 12, y: 6 }
});
btn.setOrigin(0.5);
btn.setInteractive({ useHandCursor: true });
btn.on('pointerover', () => {
btn.setScale(1.05);
if (!isActive) btn.setBackgroundColor('#2a2a4e');
if (!isActive) btn.setBackgroundColor('#8b5a3c');
});
btn.on('pointerout', () => {
btn.setScale(1.0);
if (!isActive) btn.setBackgroundColor('#1a1a2e');
if (!isActive) btn.setBackgroundColor('#6b4423');
});
btn.on('pointerdown', () => {
window.i18n.setLanguage(lang.code);

View File

@@ -66,6 +66,15 @@ class UIScene extends Phaser.Scene {
this.toggleSkillTree();
});
// Q/E za Tool Swap
this.input.keyboard.on('keydown-Q', () => {
this.swapToolPrevious();
});
this.input.keyboard.on('keydown-E', () => {
this.swapToolNext();
});
// Define Recipes
this.craftingRecipes = [
{ id: 'axe', name: 'Stone Axe', req: { 'wood': 3, 'stone': 3 }, output: 1, type: 'tool', desc: 'Used for chopping trees.' },
@@ -94,6 +103,15 @@ class UIScene extends Phaser.Scene {
this.createOxygenBar();
this.createZombieStatsPanel();
this.createFarmStatsPanel();
this.createEquipmentPreview(); // Equipment preview (top-left)
}
update() {
// Update equipment preview
this.updateEquipmentPreview();
// Update minimap
this.updateMinimap();
}
// ... (rest of class) ...
@@ -342,6 +360,11 @@ class UIScene extends Phaser.Scene {
}
drawUI() {
// Initialize i18n if not available
if (!window.i18n) {
window.i18n = new LocalizationSystem();
}
const x = 20;
const y = 20;
const width = 150; // Zmanjšana širina (300 -> 150)
@@ -349,27 +372,58 @@ class UIScene extends Phaser.Scene {
const padding = 10;
// 1. Health Bar
this.healthBar = this.drawBar(x, y, width, height, 0xff0000, 100, 'HP');
this.healthBar = this.drawBar(x, y, width, height, 0xff0000, 100, window.i18n.t('ui.hp', 'HP'));
// 2. Hunger Bar
this.hungerBar = this.drawBar(x, y + height + padding, width, height, 0xff8800, 80, 'HUN');
this.hungerBar = this.drawBar(x, y + height + padding, width, height, 0xff8800, 80, window.i18n.t('ui.hun', 'HUN'));
// 3. Thirst Bar
this.thirstBar = this.drawBar(x, y + (height + padding) * 2, width, height, 0x0088ff, 90, 'H2O');
this.thirstBar = this.drawBar(x, y + (height + padding) * 2, width, height, 0x0088ff, 90, window.i18n.t('ui.h2o', 'H2O'));
// 4. XP Bar
this.XPBar = this.drawBar(x, y + (height + padding) * 3, width, height, 0xFFD700, 0, 'XP');
this.XPBar = this.drawBar(x, y + (height + padding) * 3, width, height, 0xFFD700, 0, window.i18n.t('ui.xp', 'XP'));
// 5. Level Display
this.LevelDisplay = this.add.text(x, y + (height + padding) * 4, 'LV: 1', {
this.LevelDisplay = this.add.text(x, y + (height + padding) * 4, window.i18n.t('ui.lv', 'LV') + ': 1', {
fontSize: '18px', fontFamily: 'Courier New', fill: '#FFD700', fontStyle: 'bold'
});
}
refreshUIBars() {
// Destroy existing bars
if (this.healthBar) {
this.healthBar.bg.destroy();
this.healthBar.fill.destroy();
if (this.healthBar.label) this.healthBar.label.destroy();
}
if (this.hungerBar) {
this.hungerBar.bg.destroy();
this.hungerBar.fill.destroy();
if (this.hungerBar.label) this.hungerBar.label.destroy();
}
if (this.thirstBar) {
this.thirstBar.bg.destroy();
this.thirstBar.fill.destroy();
if (this.thirstBar.label) this.thirstBar.label.destroy();
}
if (this.XPBar) {
this.XPBar.bg.destroy();
this.XPBar.fill.destroy();
if (this.XPBar.label) this.XPBar.label.destroy();
}
if (this.LevelDisplay) {
this.LevelDisplay.destroy();
}
// Recreate with new translations
this.drawUI();
}
drawBar(x, y, width, height, color, initialPercent = 100, label = '') {
// Label
let labelText = null;
if (label) {
this.add.text(x, y - 12, label, { fontSize: '12px', fontFamily: 'Courier New', fill: '#ffffff' });
labelText = this.add.text(x, y - 12, label, { fontSize: '12px', fontFamily: 'Courier New', fill: '#ffffff' });
}
// Background
@@ -387,7 +441,7 @@ class UIScene extends Phaser.Scene {
const currentWidth = (maxWidth * initialPercent) / 100;
fill.fillRect(x + 2, y + 2, currentWidth, height - 4);
return { bg, fill, x, y, width, height, color };
return { bg, fill, label: labelText, x, y, width, height, color };
}
setBarValue(bar, percent) {
@@ -1890,10 +1944,21 @@ class UIScene extends Phaser.Scene {
if (!isActive) btn.setBackgroundColor('#222222');
});
btn.on('pointerdown', () => {
console.log('🌍 Changing language to:', lang.code);
window.i18n.setLanguage(lang.code);
// Refresh settings menu to update colors
this.toggleSettingsMenu();
// Refresh UI bars with new language
this.refreshUIBars();
// Close settings menu
this.toggleSettingsMenu();
// Close pause menu and resume game
if (this.pauseMenuActive) {
this.togglePauseMenu();
}
console.log('✅ Language changed and game resumed!');
});
this.settingsContainer.add(btn);
@@ -1920,8 +1985,11 @@ class UIScene extends Phaser.Scene {
}
togglePauseMenu() {
console.log('🎮 Toggle Pause Menu - Active:', this.pauseMenuActive);
if (this.pauseMenuActive) {
// Close pause menu
console.log('📴 Closing pause menu...');
if (this.pauseMenuContainer) {
this.pauseMenuContainer.destroy();
this.pauseMenuContainer = null;
@@ -1931,15 +1999,18 @@ class UIScene extends Phaser.Scene {
// Resume game
if (this.gameScene) {
this.gameScene.physics.resume();
console.log('▶️ Game resumed!');
}
} else {
// Open pause menu
console.log('⏸️ Opening pause menu...');
this.createPauseMenu();
this.pauseMenuActive = true;
// Pause game
if (this.gameScene) {
this.gameScene.physics.pause();
console.log('⏸️ Game paused!');
}
}
}
@@ -1957,28 +2028,30 @@ class UIScene extends Phaser.Scene {
this.pauseMenuContainer.setScrollFactor(0);
this.pauseMenuContainer.setDepth(15000);
// Semi-transparent background
const bg = this.add.rectangle(0, 0, width, height, 0x000000, 0.85);
// Warm semi-transparent background (Stardew style)
const bg = this.add.rectangle(0, 0, width, height, 0x2d1b00, 0.85);
bg.setOrigin(0);
this.pauseMenuContainer.add(bg);
// Panel
const panelW = 500;
const panelH = 550;
// Wooden panel
const panelW = 450;
const panelH = 500;
const panelX = width / 2 - panelW / 2;
const panelY = height / 2 - panelH / 2;
const panel = this.add.rectangle(panelX, panelY, panelW, panelH, 0x1a1a2e, 1);
const panel = this.add.rectangle(panelX, panelY, panelW, panelH, 0x6b4423, 1);
panel.setOrigin(0);
panel.setStrokeStyle(4, 0x00ff41);
panel.setStrokeStyle(4, 0xd4a574);
this.pauseMenuContainer.add(panel);
// Title
const title = this.add.text(width / 2, panelY + 40, '⏸️ ' + window.i18n.t('pause.title', 'PAUSED'), {
fontSize: '48px',
fontFamily: 'Courier New',
color: '#00ff41',
fontStyle: 'bold'
const title = this.add.text(width / 2, panelY + 50, window.i18n.t('pause.title', 'PAUSED'), {
fontSize: '42px',
fontFamily: 'Georgia, serif',
color: '#f4e4c1',
fontStyle: 'bold',
stroke: '#2d1b00',
strokeThickness: 4
});
title.setOrigin(0.5);
this.pauseMenuContainer.add(title);
@@ -1987,74 +2060,83 @@ class UIScene extends Phaser.Scene {
const buttons = [
{
label: window.i18n.t('pause.resume', '▶ Resume'),
color: '#00ff41',
color: '#8fbc8f',
action: () => this.togglePauseMenu()
},
{
label: window.i18n.t('pause.save', '💾 Save Game'),
color: '#4477ff',
color: '#87ceeb',
action: () => this.saveGame()
},
{
label: window.i18n.t('pause.settings', '⚙️ Settings'),
color: '#ffaa00',
color: '#daa520',
action: () => { this.togglePauseMenu(); this.toggleSettingsMenu(); }
},
{
label: window.i18n.t('pause.quit', '🚪 Quit to Menu'),
color: '#ff4444',
color: '#cd5c5c',
action: () => this.quitToMenu()
}
];
const startY = panelY + 150;
const spacing = 90;
const startY = panelY + 140;
const spacing = 80;
buttons.forEach((btn, index) => {
const y = startY + (index * spacing);
// Button background
const btnBg = this.add.rectangle(width / 2, y, 400, 70, 0x2a2a4e, 1);
btnBg.setStrokeStyle(3, btn.color);
// Wooden button background
const btnBg = this.add.rectangle(width / 2, y, 350, 60, 0x4a3520, 1);
btnBg.setStrokeStyle(3, 0xd4a574);
// Inner shadow
const innerShadow = this.add.rectangle(width / 2, y + 2, 340, 50, 0x2d1b00, 0.3);
// Button text
const btnText = this.add.text(width / 2, y, btn.label, {
fontSize: '28px',
fontFamily: 'Courier New',
fontSize: '24px',
fontFamily: 'Georgia, serif',
color: btn.color,
fontStyle: 'bold'
fontStyle: 'bold',
stroke: '#2d1b00',
strokeThickness: 3
});
btnText.setOrigin(0.5);
// Make interactive
btnBg.setInteractive({ useHandCursor: true });
btnBg.on('pointerover', () => {
btnBg.setFillStyle(0x3a3a6e);
btnBg.setFillStyle(0x6b4423);
btnText.setScale(1.05);
btnBg.setStrokeStyle(4, 0xf4e4c1);
});
btnBg.on('pointerout', () => {
btnBg.setFillStyle(0x2a2a4e);
btnBg.setFillStyle(0x4a3520);
btnText.setScale(1.0);
btnBg.setStrokeStyle(3, 0xd4a574);
});
btnBg.on('pointerdown', () => {
this.tweens.add({
targets: btnBg,
alpha: 0.5,
yoyo: true,
targets: [btnBg, btnText, innerShadow],
y: y + 3,
duration: 100,
yoyo: true,
onComplete: btn.action
});
});
this.pauseMenuContainer.add(innerShadow);
this.pauseMenuContainer.add(btnBg);
this.pauseMenuContainer.add(btnText);
});
// Hint text
const hint = this.add.text(width / 2, panelY + panelH - 30, window.i18n.t('pause.hint', 'Press ESC to resume'), {
fontSize: '16px',
fontFamily: 'Courier New',
color: '#888888'
const hint = this.add.text(width / 2, panelY + panelH - 40, window.i18n.t('pause.hint', 'Press ESC to resume'), {
fontSize: '14px',
fontFamily: 'Georgia, serif',
color: '#d4a574',
fontStyle: 'italic'
});
hint.setOrigin(0.5);
this.pauseMenuContainer.add(hint);
@@ -2099,8 +2181,8 @@ class UIScene extends Phaser.Scene {
// ========== NEW: ZOMBIE & FARM STATS PANELS ==========
createZombieStatsPanel() {
const panelWidth = 220;
const panelHeight = 140;
const panelWidth = 180;
const panelHeight = 130;
const x = 20;
const y = 120; // Below player stats
@@ -2117,8 +2199,8 @@ class UIScene extends Phaser.Scene {
this.zombieStatsContainer.add(bg);
// Title
const title = this.add.text(panelWidth / 2, 15, '🧟 ZOMBIE WORKER', {
fontSize: '14px',
const title = this.add.text(panelWidth / 2, 12, '🧟 ZOMBIE', {
fontSize: '12px',
fontFamily: 'Courier New',
fill: '#8a2be2',
fontStyle: 'bold'
@@ -2126,29 +2208,29 @@ class UIScene extends Phaser.Scene {
this.zombieStatsContainer.add(title);
// Stats Text
this.zombieNameText = this.add.text(10, 35, 'Name: Worker #1', {
fontSize: '12px',
this.zombieNameText = this.add.text(8, 30, 'Name: Worker #1', {
fontSize: '10px',
fill: '#ffffff'
});
this.zombieStatsContainer.add(this.zombieNameText);
this.zombieTaskText = this.add.text(10, 55, 'Task: IDLE', {
fontSize: '12px',
this.zombieTaskText = this.add.text(8, 48, 'Task: IDLE', {
fontSize: '10px',
fill: '#ffff00'
});
this.zombieStatsContainer.add(this.zombieTaskText);
this.zombieLevelText = this.add.text(10, 75, 'Level: 1 (0/100 XP)', {
fontSize: '12px',
this.zombieLevelText = this.add.text(8, 66, 'Level: 1 (0/100 XP)', {
fontSize: '10px',
fill: '#00ff00'
});
this.zombieStatsContainer.add(this.zombieLevelText);
// Energy Bar
const energyLabel = this.add.text(10, 95, 'ENERGY:', { fontSize: '11px', fill: '#aaaaaa' });
const energyLabel = this.add.text(8, 84, 'ENERGY:', { fontSize: '9px', fill: '#aaaaaa' });
this.zombieStatsContainer.add(energyLabel);
this.zombieEnergyBar = this.drawMiniBar(10, 110, panelWidth - 20, 15, 0x00aaff, 100);
this.zombieEnergyBar = this.drawMiniBar(8, 98, panelWidth - 16, 12, 0x00aaff, 100);
this.zombieStatsContainer.add(this.zombieEnergyBar.bg);
this.zombieStatsContainer.add(this.zombieEnergyBar.fill);
@@ -2157,10 +2239,10 @@ class UIScene extends Phaser.Scene {
}
createFarmStatsPanel() {
const panelWidth = 220;
const panelHeight = 120;
const panelWidth = 180;
const panelHeight = 110;
const x = 20;
const y = 280; // Below zombie stats
const y = 270; // Below zombie stats
// Container
this.farmStatsContainer = this.add.container(x, y);
@@ -2175,8 +2257,8 @@ class UIScene extends Phaser.Scene {
this.farmStatsContainer.add(bg);
// Title
const title = this.add.text(panelWidth / 2, 15, '🌾 FARM STATS', {
fontSize: '14px',
const title = this.add.text(panelWidth / 2, 12, '🌾 FARM', {
fontSize: '12px',
fontFamily: 'Courier New',
fill: '#00ff00',
fontStyle: 'bold'
@@ -2184,26 +2266,26 @@ class UIScene extends Phaser.Scene {
this.farmStatsContainer.add(title);
// Stats
this.farmCropsPlantedText = this.add.text(10, 40, 'Crops Planted: 0', {
fontSize: '12px',
this.farmCropsPlantedText = this.add.text(8, 32, 'Planted: 0', {
fontSize: '10px',
fill: '#ffffff'
});
this.farmStatsContainer.add(this.farmCropsPlantedText);
this.farmCropsHarvestedText = this.add.text(10, 60, 'Total Harvested: 0', {
fontSize: '12px',
this.farmCropsHarvestedText = this.add.text(8, 50, 'Harvested: 0', {
fontSize: '10px',
fill: '#ffff00'
});
this.farmStatsContainer.add(this.farmCropsHarvestedText);
this.farmGoldEarnedText = this.add.text(10, 80, 'Gold Earned: 0g', {
fontSize: '12px',
this.farmGoldEarnedText = this.add.text(8, 68, 'Gold: 0g', {
fontSize: '10px',
fill: '#ffd700'
});
this.farmStatsContainer.add(this.farmGoldEarnedText);
this.farmDaysText = this.add.text(10, 100, 'Days Farmed: 0', {
fontSize: '12px',
this.farmDaysText = this.add.text(8, 86, 'Days: 0', {
fontSize: '10px',
fill: '#aaaaaa'
});
this.farmStatsContainer.add(this.farmDaysText);
@@ -2252,10 +2334,10 @@ class UIScene extends Phaser.Scene {
updateFarmStats(stats) {
if (!stats || !this.farmStatsContainer) return;
if (this.farmCropsPlantedText) this.farmCropsPlantedText.setText(`Crops Planted: ${stats.cropsPlanted || 0}`);
if (this.farmCropsHarvestedText) this.farmCropsHarvestedText.setText(`Total Harvested: ${stats.totalHarvested || 0}`);
if (this.farmGoldEarnedText) this.farmGoldEarnedText.setText(`Gold Earned: ${stats.goldEarned || 0}g`);
if (this.farmDaysText) this.farmDaysText.setText(`Days Farmed: ${stats.daysFarmed || 0}`);
if (this.farmCropsPlantedText) this.farmCropsPlantedText.setText(`Planted: ${stats.cropsPlanted || 0}`);
if (this.farmCropsHarvestedText) this.farmCropsHarvestedText.setText(`Harvested: ${stats.totalHarvested || 0}`);
if (this.farmGoldEarnedText) this.farmGoldEarnedText.setText(`Gold: ${stats.goldEarned || 0}g`);
if (this.farmDaysText) this.farmDaysText.setText(`Days: ${stats.daysFarmed || 0}`);
}
createMinimap() {
@@ -2365,5 +2447,108 @@ class UIScene extends Phaser.Scene {
});
}
}
}
// Q/E Tool Swap Methods
swapToolPrevious() {
if (!this.gameScene || !this.gameScene.inventorySystem) return;
const inv = this.gameScene.inventorySystem;
// Cycle backwards
let newSlot = inv.selectedSlot - 1;
if (newSlot < 0) newSlot = 8;
this.selectSlot(newSlot);
// Sound effect
if (this.gameScene.soundManager) {
this.gameScene.soundManager.beepUIClick();
}
console.log(`🔄 Tool swap: Slot ${newSlot}`);
}
swapToolNext() {
if (!this.gameScene || !this.gameScene.inventorySystem) return;
const inv = this.gameScene.inventorySystem;
// Cycle forwards
let newSlot = inv.selectedSlot + 1;
if (newSlot > 8) newSlot = 0;
this.selectSlot(newSlot);
// Sound effect
if (this.gameScene.soundManager) {
this.gameScene.soundManager.beepUIClick();
}
console.log(`🔄 Tool swap: Slot ${newSlot}`);
}
// Equipment Preview
createEquipmentPreview() {
const previewX = 20;
const previewY = 150;
// Background
this.equipmentBg = this.add.graphics();
this.equipmentBg.fillStyle(0x000000, 0.6);
this.equipmentBg.fillRoundedRect(previewX, previewY, 80, 80, 8);
this.equipmentBg.setScrollFactor(0);
this.equipmentBg.setDepth(1000);
// Label
this.equipmentLabel = this.add.text(
previewX + 40,
previewY - 5,
'EQUIPPED',
{
font: 'bold 10px Arial',
fill: '#ffff00'
}
);
this.equipmentLabel.setOrigin(0.5, 1);
this.equipmentLabel.setScrollFactor(0);
this.equipmentLabel.setDepth(1001);
// Icon sprite placeholder
this.equipmentIcon = this.add.rectangle(previewX + 40, previewY + 40, 32, 32, 0x888888);
this.equipmentIcon.setScrollFactor(0);
this.equipmentIcon.setDepth(1001);
// Tool name
this.equipmentName = this.add.text(
previewX + 40,
previewY + 75,
'None',
{
font: 'bold 12px Arial',
fill: '#ffffff'
}
);
this.equipmentName.setOrigin(0.5, 0);
this.equipmentName.setScrollFactor(0);
this.equipmentName.setDepth(1001);
console.log('🎮 Equipment preview created!');
}
updateEquipmentPreview() {
if (!this.gameScene || !this.gameScene.inventorySystem) return;
if (!this.equipmentName) return;
const inv = this.gameScene.inventorySystem;
const selectedItem = inv.items[inv.selectedSlot];
if (selectedItem) {
// Update name
this.equipmentName.setText(selectedItem.name || selectedItem.id);
this.equipmentIcon.setVisible(true);
this.equipmentName.setVisible(true);
} else {
// Hide if no item
this.equipmentName.setText('None');
this.equipmentIcon.setVisible(false);
}
}
}