neki bo
This commit is contained in:
BIN
assets/.DS_Store
vendored
BIN
assets/.DS_Store
vendored
Binary file not shown.
BIN
assets/DEMO_FAZA1/.DS_Store
vendored
BIN
assets/DEMO_FAZA1/.DS_Store
vendored
Binary file not shown.
BIN
nova farma TRAE/.DS_Store
vendored
BIN
nova farma TRAE/.DS_Store
vendored
Binary file not shown.
BIN
nova farma TRAE/assets/.DS_Store
vendored
BIN
nova farma TRAE/assets/.DS_Store
vendored
Binary file not shown.
BIN
nova farma TRAE/assets/DEMO_FAZA1/.DS_Store
vendored
BIN
nova farma TRAE/assets/DEMO_FAZA1/.DS_Store
vendored
Binary file not shown.
@@ -4,6 +4,10 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Nova Farma - Clean Start</title>
|
<title>Nova Farma - Clean Start</title>
|
||||||
|
<!-- Google Fonts za UTF-8 in šumnike -->
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;700&family=Noto+Sans+SC:wght@400;700&display=swap" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|||||||
97
nova farma TRAE/public/assets/localization.json
Normal file
97
nova farma TRAE/public/assets/localization.json
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
{
|
||||||
|
"sl": {
|
||||||
|
"menu_play": "IGRAJ",
|
||||||
|
"menu_options": "NASTAVITVE",
|
||||||
|
"menu_exit": "IZHOD",
|
||||||
|
"lang_btn": "JEZIK: SL",
|
||||||
|
"acc_menu": "MENI ZA DOSTOPNOST",
|
||||||
|
"acc_deaf": "🔊 Vizualna Opozorila (Deaf Mode)",
|
||||||
|
"acc_autism": "⚡ Senzorni Način (Reduce Motion)",
|
||||||
|
"acc_adhd": "🎯 Zen/ADHD Način (Fokus Cilja)",
|
||||||
|
"acc_font": "🔎 Povečana Pisava",
|
||||||
|
"acc_contrast": "🔲 Visok Kontrast",
|
||||||
|
"acc_colorblind": "👁️ Filter Barvne Slepote",
|
||||||
|
"acc_onehand": "🕹️ Enoročni Način",
|
||||||
|
"acc_close": "[ X ZAPRI ]",
|
||||||
|
"day": "DAN",
|
||||||
|
"map": "MAPA",
|
||||||
|
"crafting": "CRAFTING",
|
||||||
|
"adhd_goal": "⬇️ TVOJ TRENUTNI CILJ: ZALIJ PŠENICO! ⬇️"
|
||||||
|
},
|
||||||
|
"en": {
|
||||||
|
"menu_play": "PLAY",
|
||||||
|
"menu_options": "OPTIONS",
|
||||||
|
"menu_exit": "EXIT",
|
||||||
|
"lang_btn": "LANGUAGE: EN",
|
||||||
|
"acc_menu": "ACCESSIBILITY MENU",
|
||||||
|
"acc_deaf": "🔊 Visual Alerts (Deaf Mode)",
|
||||||
|
"acc_autism": "⚡ Sensory Mode (Reduce Motion)",
|
||||||
|
"acc_adhd": "🎯 Zen/ADHD Mode (Goal Focus)",
|
||||||
|
"acc_font": "🔎 Large Font",
|
||||||
|
"acc_contrast": "🔲 High Contrast",
|
||||||
|
"acc_colorblind": "👁️ Colorblind Filter",
|
||||||
|
"acc_onehand": "🕹️ One-handed Mode",
|
||||||
|
"acc_close": "[ X CLOSE ]",
|
||||||
|
"day": "DAY",
|
||||||
|
"map": "MAP",
|
||||||
|
"crafting": "CRAFTING",
|
||||||
|
"adhd_goal": "⬇️ YOUR CURRENT GOAL: WATER THE WHEAT! ⬇️"
|
||||||
|
},
|
||||||
|
"de": {
|
||||||
|
"menu_play": "SPIELEN",
|
||||||
|
"menu_options": "OPTIONEN",
|
||||||
|
"menu_exit": "BEENDEN",
|
||||||
|
"lang_btn": "SPRACHE: DE",
|
||||||
|
"acc_menu": "BARRIEREFREIHEITS-MENÜ",
|
||||||
|
"acc_deaf": "🔊 Visuelle Alarme (Gehörlosenmodus)",
|
||||||
|
"acc_autism": "⚡ Sensibler Modus (Weniger Bewegung)",
|
||||||
|
"acc_adhd": "🎯 Zen/ADHD-Modus (Zielfokus)",
|
||||||
|
"acc_font": "🔎 Große Schrift",
|
||||||
|
"acc_contrast": "🔲 Hoher Kontrast",
|
||||||
|
"acc_colorblind": "👁️ Farbenblind-Filter",
|
||||||
|
"acc_onehand": "🕹️ Einhandmodus",
|
||||||
|
"acc_close": "[ X SCHLIESSEN ]",
|
||||||
|
"day": "TAG",
|
||||||
|
"map": "KARTE",
|
||||||
|
"crafting": "HERSTELLUNG",
|
||||||
|
"adhd_goal": "⬇️ DEIN AKTUELLES ZIEL: WEIZEN GIESSEN! ⬇️"
|
||||||
|
},
|
||||||
|
"it": {
|
||||||
|
"menu_play": "GIOCA",
|
||||||
|
"menu_options": "OPZIONI",
|
||||||
|
"menu_exit": "ESCI",
|
||||||
|
"lang_btn": "LINGUA: IT",
|
||||||
|
"acc_menu": "MENU ACCESSIBILITÀ",
|
||||||
|
"acc_deaf": "🔊 Avvisi Visivi (Modalità Sordi)",
|
||||||
|
"acc_autism": "⚡ Modalità Sensoriale (Riduci Movimento)",
|
||||||
|
"acc_adhd": "🎯 Modalità Zen/ADHD (Focus Obiettivo)",
|
||||||
|
"acc_font": "🔎 Carattere Grande",
|
||||||
|
"acc_contrast": "🔲 Alto Contrasto",
|
||||||
|
"acc_colorblind": "👁️ Filtro Daltonismo",
|
||||||
|
"acc_onehand": "🕹️ Modalità Una Mano",
|
||||||
|
"acc_close": "[ X CHIUDI ]",
|
||||||
|
"day": "GIORNO",
|
||||||
|
"map": "MAPPA",
|
||||||
|
"crafting": "CREAZIONE",
|
||||||
|
"adhd_goal": "⬇️ IL TUO OBIETTIVO ATTUALE: ANNAFFIA IL GRANO! ⬇️"
|
||||||
|
},
|
||||||
|
"cn": {
|
||||||
|
"menu_play": "开始游戏",
|
||||||
|
"menu_options": "设置",
|
||||||
|
"menu_exit": "退出",
|
||||||
|
"lang_btn": "语言: CN",
|
||||||
|
"acc_menu": "无障碍菜单",
|
||||||
|
"acc_deaf": "🔊 视觉警报 (聋人模式)",
|
||||||
|
"acc_autism": "⚡ 感觉模式 (减少动画)",
|
||||||
|
"acc_adhd": "🎯 禅/ADHD模式 (目标专注)",
|
||||||
|
"acc_font": "🔎 大字体",
|
||||||
|
"acc_contrast": "🔲 高对比度",
|
||||||
|
"acc_colorblind": "👁️ 色盲滤镜",
|
||||||
|
"acc_onehand": "🕹️ 单手模式",
|
||||||
|
"acc_close": "[ X 关闭 ]",
|
||||||
|
"day": "天",
|
||||||
|
"map": "地图",
|
||||||
|
"crafting": "制作",
|
||||||
|
"adhd_goal": "⬇️ 你当前的目标:给小麦浇水! ⬇️"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -293,12 +293,12 @@ export default class GrassSceneClean extends Phaser.Scene {
|
|||||||
this.cameras.main.setBackgroundColor('#001d3d'); // Deep Blue Ocean
|
this.cameras.main.setBackgroundColor('#001d3d'); // Deep Blue Ocean
|
||||||
|
|
||||||
// --- ZOOM CONTROL ---
|
// --- ZOOM CONTROL ---
|
||||||
this.cameras.main.setZoom(0.8);
|
this.cameras.main.setZoom(1.0); // Privzet zoom za Demo
|
||||||
|
|
||||||
this.input.on('wheel', (pointer, gameObjects, deltaX, deltaY, deltaZ) => {
|
this.input.on('wheel', (pointer, gameObjects, deltaX, deltaY, deltaZ) => {
|
||||||
const zoomFactor = -0.001;
|
const zoomFactor = -0.001;
|
||||||
const newZoom = this.cameras.main.zoom + deltaY * zoomFactor;
|
const newZoom = this.cameras.main.zoom + deltaY * zoomFactor;
|
||||||
this.cameras.main.setZoom(Phaser.Math.Clamp(newZoom, 0.2, 5.0));
|
this.cameras.main.setZoom(Phaser.Math.Clamp(newZoom, 0.5, 2.5)); // Omejitev 0.5 do 2.5
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- 1. DYNAMIC OCEAN & ISLAND SYSTEM ---
|
// --- 1. DYNAMIC OCEAN & ISLAND SYSTEM ---
|
||||||
@@ -674,7 +674,9 @@ export default class GrassSceneClean extends Phaser.Scene {
|
|||||||
/*
|
/*
|
||||||
// Trnje (Thorns) - Draggable
|
// Trnje (Thorns) - Draggable
|
||||||
this.trnje = this.add.image(startX - 200, startY + 100, 'trnje');
|
this.trnje = this.add.image(startX - 200, startY + 100, 'trnje');
|
||||||
|
this.trnje.setOrigin(0.5, 1.0); // Sidrišče čisto na dno
|
||||||
this.trnje.setScale(0.5); // Adjust scale if needed
|
this.trnje.setScale(0.5); // Adjust scale if needed
|
||||||
|
this.trnje.setDepth(this.trnje.y); // Y-sorting
|
||||||
this.trnje.setInteractive({ draggable: true });
|
this.trnje.setInteractive({ draggable: true });
|
||||||
// Trigger Amnesia Clear on interaction
|
// Trigger Amnesia Clear on interaction
|
||||||
this.trnje.on('pointerdown', () => {
|
this.trnje.on('pointerdown', () => {
|
||||||
@@ -683,9 +685,10 @@ export default class GrassSceneClean extends Phaser.Scene {
|
|||||||
|
|
||||||
// --- NEW: RAIN CATCHER ---
|
// --- NEW: RAIN CATCHER ---
|
||||||
this.rainCatcher = this.physics.add.image(startX + 150, startY + 50, 'rain_catcher');
|
this.rainCatcher = this.physics.add.image(startX + 150, startY + 50, 'rain_catcher');
|
||||||
|
this.rainCatcher.setOrigin(0.5, 1.0); // Sidrišče čisto na dno
|
||||||
this.rainCatcher.setScale(0.8);
|
this.rainCatcher.setScale(0.8);
|
||||||
this.rainCatcher.setInteractive({ draggable: true });
|
this.rainCatcher.setInteractive({ draggable: true });
|
||||||
this.rainCatcher.setDepth(startY + 50); // Y-sort
|
this.rainCatcher.setDepth(this.rainCatcher.y); // Y-sort
|
||||||
this.rainCatcher.body.setImmovable(true);
|
this.rainCatcher.body.setImmovable(true);
|
||||||
// Collider added later with Kai
|
// Collider added later with Kai
|
||||||
*/
|
*/
|
||||||
@@ -993,21 +996,35 @@ export default class GrassSceneClean extends Phaser.Scene {
|
|||||||
|
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
// ─── SPALNA VREČA & STARTER CHEST (Kišta) ────────────────────────
|
// ─── HARDCODED DEMO BASE (8x8) ────────────────────────
|
||||||
this.sleepingBag = this.physics.add.image(SPAWN_X + 150, 5600, 'sleeping_bag');
|
// Zgoraj Levo: Šotor (2x2)
|
||||||
this.sleepingBag.setOrigin(0.5, 1.0);
|
this.sotor = this.physics.add.image(SPAWN_X - 128, SPAWN_Y - 128, 'sotor');
|
||||||
this.sleepingBag.setScale(0.3);
|
this.sotor.setOrigin(0.5, 1.0);
|
||||||
this.sleepingBag.setDepth(this.sleepingBag.y);
|
this.sotor.setScale(2.5); // iz BuildingSystem.js
|
||||||
|
this.sotor.setDepth(this.sotor.y);
|
||||||
|
this.sotor.body.setSize(160, 40);
|
||||||
|
this.sotor.body.setOffset(-80, -40);
|
||||||
|
this.sotor.body.setImmovable(true);
|
||||||
|
this.sleepingBag = this.sotor; // Uporabi šotor kot checkpoint za spanje
|
||||||
|
|
||||||
this.starterChest = this.physics.add.image(SPAWN_X - 100, 5600, 'chest_closed');
|
// Sredina: Taborni ogenj (1x1)
|
||||||
this.starterChest.setOrigin(0.5, 1.0);
|
this.campfire = this.physics.add.image(SPAWN_X - 32, SPAWN_Y - 32, 'campfire');
|
||||||
|
this.campfire.setOrigin(0.5, 1.0);
|
||||||
|
this.campfire.setDepth(this.campfire.y);
|
||||||
|
this.campfire.body.setSize(50, 20);
|
||||||
|
this.campfire.body.setOffset(25, 30);
|
||||||
|
this.campfire.body.setImmovable(true);
|
||||||
|
|
||||||
|
// Sredina: Skrinja
|
||||||
|
this.starterChest = this.physics.add.image(SPAWN_X + 64, SPAWN_Y - 32, 'chest_closed');
|
||||||
|
this.starterChest.setOrigin(0.5, 1.0); // Sidrišče čisto na dno
|
||||||
this.starterChest.setScale(0.18);
|
this.starterChest.setScale(0.18);
|
||||||
this.starterChest.setDepth(5600);
|
this.starterChest.setDepth(this.starterChest.y); // Y-sorting
|
||||||
this.starterChest.body.setSize(this.starterChest.width * 0.18, this.starterChest.height * 0.18);
|
this.starterChest.body.setSize(this.starterChest.width * 0.18, this.starterChest.height * 0.18);
|
||||||
this.starterChest.body.setImmovable(true);
|
this.starterChest.body.setImmovable(true);
|
||||||
this.starterChest.opened = false;
|
this.starterChest.opened = false;
|
||||||
|
|
||||||
let chestText = this.add.text(SPAWN_X - 100, 5600 - 100, '[E] Odpri Kišto', { fontFamily: 'Arial Black', fontSize: '13px', color: '#ffdd00', stroke: '#000', strokeThickness: 4, align: 'center' }).setOrigin(0.5, 0.5);
|
let chestText = this.add.text(this.starterChest.x, this.starterChest.y - 50, '[E] Odpri Kišto', { fontFamily: 'Arial Black', fontSize: '13px', color: '#ffdd00', stroke: '#000', strokeThickness: 4, align: 'center' }).setOrigin(0.5, 0.5);
|
||||||
chestText.setDepth(9999);
|
chestText.setDepth(9999);
|
||||||
|
|
||||||
this.input.keyboard.on('keydown-E', () => {
|
this.input.keyboard.on('keydown-E', () => {
|
||||||
@@ -1041,42 +1058,41 @@ export default class GrassSceneClean extends Phaser.Scene {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
// ─────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────
|
||||||
// === RANDOM TREE GENERATION (AUTO-LOADER) ===
|
// === NEPREBOJEN GOZD (IMPENETRABLE FOREST WALL) ===
|
||||||
this.treesGroup = this.physics.add.staticGroup();
|
this.treesGroup = this.physics.add.staticGroup();
|
||||||
|
|
||||||
const treeKeys = ['tree_adult_0', 'tree_adult_1', 'tree_adult_2', 'tree_adult_3', 'tree_adult_4', 'tree_adult_5'];
|
const treeKeys = ['tree_adult_0', 'tree_adult_1', 'tree_adult_2', 'tree_adult_3', 'tree_adult_4', 'tree_adult_5'];
|
||||||
const TREE_COUNT = 40;
|
const TREE_RADIUS = 400; // Velikost 8x8 cone
|
||||||
|
|
||||||
for (let i = 0; i < TREE_COUNT; i++) {
|
|
||||||
// Place on random edge to keep center farming area free
|
|
||||||
const edge = Math.floor(Math.random() * 4);
|
|
||||||
let tx, ty;
|
|
||||||
const PADDING = 200;
|
|
||||||
|
|
||||||
switch (edge) {
|
|
||||||
case 0: // Top
|
|
||||||
tx = this.islandX + Math.random() * this.islandWidth;
|
|
||||||
ty = this.islandY + PADDING + Math.random() * 300;
|
|
||||||
break;
|
|
||||||
case 1: // Right
|
|
||||||
tx = this.islandX + this.islandWidth - PADDING - Math.random() * 300;
|
|
||||||
ty = this.islandY + Math.random() * this.islandHeight;
|
|
||||||
break;
|
|
||||||
case 2: // Bottom
|
|
||||||
tx = this.islandX + Math.random() * this.islandWidth;
|
|
||||||
ty = this.islandY + this.islandHeight - PADDING - Math.random() * 300;
|
|
||||||
break;
|
|
||||||
case 3: // Left
|
|
||||||
tx = this.islandX + PADDING + Math.random() * 300;
|
|
||||||
ty = this.islandY + Math.random() * this.islandHeight;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Inner dense circle
|
||||||
|
for (let angle = 0; angle < Math.PI * 2; angle += 0.25) {
|
||||||
|
let tx = SPAWN_X + Math.cos(angle) * TREE_RADIUS + (Math.random() - 0.5) * 60;
|
||||||
|
let ty = SPAWN_Y + Math.sin(angle) * TREE_RADIUS + (Math.random() - 0.5) * 60;
|
||||||
let tKey = Phaser.Utils.Array.GetRandom(treeKeys);
|
let tKey = Phaser.Utils.Array.GetRandom(treeKeys);
|
||||||
let t = this.loadTree(tx, ty, tKey);
|
let t = this.loadTree(tx, ty, tKey);
|
||||||
t.setMask(this.islandMask);
|
if(t) this.treesGroup.add(t);
|
||||||
this.treesGroup.add(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Outer dense circle
|
||||||
|
for (let angle = 0; angle < Math.PI * 2; angle += 0.15) {
|
||||||
|
let tx = SPAWN_X + Math.cos(angle) * (TREE_RADIUS + 120) + (Math.random() - 0.5) * 80;
|
||||||
|
let ty = SPAWN_Y + Math.sin(angle) * (TREE_RADIUS + 120) + (Math.random() - 0.5) * 80;
|
||||||
|
let tKey = Phaser.Utils.Array.GetRandom(treeKeys);
|
||||||
|
let t = this.loadTree(tx, ty, tKey);
|
||||||
|
if(t) this.treesGroup.add(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// === FOG OF WAR (Temna megla izven baze) ===
|
||||||
|
this.fowGraphics = this.add.graphics();
|
||||||
|
this.fowGraphics.setDepth(6000);
|
||||||
|
this.fowGraphics.fillStyle(0x0a0f12, 0.98); // Zelo temno modro-siva megla
|
||||||
|
|
||||||
|
// Narišemo 4 pravokotnike, ki pustijo luknjo na sredini
|
||||||
|
const FOW_R = TREE_RADIUS + 60;
|
||||||
|
this.fowGraphics.fillRect(0, 0, WORLD_W, SPAWN_Y - FOW_R); // Zgoraj
|
||||||
|
this.fowGraphics.fillRect(0, SPAWN_Y + FOW_R, WORLD_W, WORLD_H); // Spodaj
|
||||||
|
this.fowGraphics.fillRect(0, SPAWN_Y - FOW_R, SPAWN_X - FOW_R, FOW_R * 2); // Levo
|
||||||
|
this.fowGraphics.fillRect(SPAWN_X + FOW_R, SPAWN_Y - FOW_R, WORLD_W, FOW_R * 2); // Desno
|
||||||
|
|
||||||
// Add solid collision against trees!
|
// Add solid collision against trees!
|
||||||
this.physics.add.collider(this.kai, this.treesGroup);
|
this.physics.add.collider(this.kai, this.treesGroup);
|
||||||
@@ -1094,8 +1110,9 @@ export default class GrassSceneClean extends Phaser.Scene {
|
|||||||
// REMOVED PER USER REQUEST
|
// REMOVED PER USER REQUEST
|
||||||
/*
|
/*
|
||||||
this.gronk = this.physics.add.sprite(startX - 150, startY - 100, 'gronk');
|
this.gronk = this.physics.add.sprite(startX - 150, startY - 100, 'gronk');
|
||||||
|
this.gronk.setOrigin(0.5, 1.0); // Sidrišče čisto na dno
|
||||||
this.gronk.setScale(0.8); // Gronk is big!
|
this.gronk.setScale(0.8); // Gronk is big!
|
||||||
this.gronk.setDepth(startY - 100);
|
this.gronk.setDepth(this.gronk.y); // Y-sorting
|
||||||
this.gronk.setImmovable(true);
|
this.gronk.setImmovable(true);
|
||||||
this.gronk.body.setSize(80, 60);
|
this.gronk.body.setSize(80, 60);
|
||||||
this.gronk.body.setOffset(88, 190); // Adjusted for 256x256 frame
|
this.gronk.body.setOffset(88, 190); // Adjusted for 256x256 frame
|
||||||
@@ -1152,8 +1169,11 @@ export default class GrassSceneClean extends Phaser.Scene {
|
|||||||
this.kai.stop();
|
this.kai.stop();
|
||||||
|
|
||||||
// Camera setup logic
|
// Camera setup logic
|
||||||
this.cameras.main.startFollow(this.kai, true, 0.1, 0.1);
|
this.cameras.main.startFollow(this.kai, true, 0.08, 0.08); // Zelo mehko sledenje
|
||||||
this.cameras.main.setRoundPixels(true); // Prevent jitter
|
this.cameras.main.setRoundPixels(true); // Prevent jitter
|
||||||
|
|
||||||
|
// Spremenljivka za gladko drsenje kamere naprej
|
||||||
|
this.cameraLookahead = { x: 0, y: 0 };
|
||||||
this.cursors = this.input.keyboard.createCursorKeys();
|
this.cursors = this.input.keyboard.createCursorKeys();
|
||||||
// Add WASD keys
|
// Add WASD keys
|
||||||
this.keys = this.input.keyboard.addKeys({
|
this.keys = this.input.keyboard.addKeys({
|
||||||
@@ -1348,14 +1368,25 @@ export default class GrassSceneClean extends Phaser.Scene {
|
|||||||
|
|
||||||
console.log('✅ FarmingSystem ready — [E] ore, posadi, zalij, pozeni!');
|
console.log('✅ FarmingSystem ready — [E] ore, posadi, zalij, pozeni!');
|
||||||
|
|
||||||
|
// Spodaj: Fiksno zgenerirana polja za kmetovanje
|
||||||
|
const farmStartX = this.islandX + this.islandWidth / 2 - 80;
|
||||||
|
const farmStartY = this.islandY + this.islandHeight / 2 + 140;
|
||||||
|
for (let i = 0; i < 4; i++) {
|
||||||
|
for (let j = 0; j < 2; j++) {
|
||||||
|
if (this.farmingSystem._tillGround) {
|
||||||
|
this.farmingSystem._tillGround(farmStartX + i * 48, farmStartY + j * 48);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ─── WATER SYSTEM ────────────────────────────────────────
|
// ─── WATER SYSTEM ────────────────────────────────────────
|
||||||
this.waterSystem = new WaterSystem(this, {
|
this.waterSystem = new WaterSystem(this, {
|
||||||
tileSize: this.TILE_SIZE,
|
tileSize: this.TILE_SIZE,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Postavi Rain Catcher blizu centra otoka (kamor Kai spawn-a)
|
// Zgoraj Desno: Lovilec deževnice (Fiksno za DEMO)
|
||||||
const rcX = this.islandX + this.islandWidth / 2 + 200;
|
const rcX = this.islandX + this.islandWidth / 2 + 128;
|
||||||
const rcY = this.islandY + this.islandHeight / 2;
|
const rcY = this.islandY + this.islandHeight / 2 - 128;
|
||||||
this.waterSystem.placeRainCatcher(rcX, rcY);
|
this.waterSystem.placeRainCatcher(rcX, rcY);
|
||||||
|
|
||||||
// Poveži water system z farming sistemom (preverj vodo pred zalivanjem)
|
// Poveži water system z farming sistemom (preverj vodo pred zalivanjem)
|
||||||
@@ -1373,7 +1404,16 @@ export default class GrassSceneClean extends Phaser.Scene {
|
|||||||
|
|
||||||
// ─── DAY/NIGHT SYSTEM ─────────────────────────────────
|
// ─── DAY/NIGHT SYSTEM ─────────────────────────────────
|
||||||
this.dayNightSystem = new DayNightSystem(this, {
|
this.dayNightSystem = new DayNightSystem(this, {
|
||||||
speed: 1, // 1 sec real = 1 min igre (24 min = 1 dan)
|
speed: 1.2, // 1.2 sec igre na 1 realno sec (20 minut = 1 dan)
|
||||||
|
});
|
||||||
|
|
||||||
|
// ─── ACCESSIBILITY SYSTEM ─────────────────────────────
|
||||||
|
this.accessState = {
|
||||||
|
deafMode: false, autismMode: false, adhdMode: false,
|
||||||
|
fontMode: false, contrastMode: false, colorblindMode: false, onehandMode: false
|
||||||
|
};
|
||||||
|
this.game.events.on('accessibility-changed', (state) => {
|
||||||
|
this.accessState = state;
|
||||||
});
|
});
|
||||||
|
|
||||||
// === EVENT WIRE-UP ===
|
// === EVENT WIRE-UP ===
|
||||||
@@ -1459,6 +1499,63 @@ export default class GrassSceneClean extends Phaser.Scene {
|
|||||||
|
|
||||||
console.log('✅ ZombieSystem ready — [SPACE] za Alfa Moč!');
|
console.log('✅ ZombieSystem ready — [SPACE] za Alfa Moč!');
|
||||||
|
|
||||||
|
// ─── ODKLEP FAZA 1 (FOG OF WAR LIFT) ──────────────────────
|
||||||
|
this.game.events.on('unlock-faza1', () => {
|
||||||
|
console.log("🔓 FAZA 1 ODKLENJENA! Zmegljen Fog of War, odklenjene zgradbe.");
|
||||||
|
|
||||||
|
// 1. Vizualni indikator umikanja megle
|
||||||
|
const cx = this.cameras.main.centerX;
|
||||||
|
const cy = this.cameras.main.centerY;
|
||||||
|
let fogLiftText = this.add.text(cx, cy - 150, 'NOVA OBMOČJA ODKRITA\n(Megla vojne se dviga)', {
|
||||||
|
fontFamily: 'Arial Black',
|
||||||
|
fontSize: '42px',
|
||||||
|
color: '#44aaff',
|
||||||
|
stroke: '#000',
|
||||||
|
strokeThickness: 8,
|
||||||
|
align: 'center'
|
||||||
|
}).setScrollFactor(0).setOrigin(0.5, 0.5).setDepth(9999).setAlpha(0);
|
||||||
|
|
||||||
|
this.tweens.add({
|
||||||
|
targets: fogLiftText,
|
||||||
|
alpha: 1,
|
||||||
|
y: cy - 200,
|
||||||
|
duration: 2000,
|
||||||
|
ease: 'Sine.easeOut',
|
||||||
|
yoyo: true,
|
||||||
|
hold: 3000,
|
||||||
|
onComplete: () => fogLiftText.destroy()
|
||||||
|
});
|
||||||
|
|
||||||
|
// Umik Fog Of War grafike
|
||||||
|
if (this.fowGraphics) {
|
||||||
|
this.tweens.add({
|
||||||
|
targets: this.fowGraphics,
|
||||||
|
alpha: 0,
|
||||||
|
duration: 3000,
|
||||||
|
ease: 'Sine.easeInOut',
|
||||||
|
onComplete: () => this.fowGraphics.destroy()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Dodamo nove zgradbe v BuildingSystem
|
||||||
|
if (this.buildingSystem) {
|
||||||
|
this.buildingSystem.catalogue.push(
|
||||||
|
{
|
||||||
|
key: 'garage_ruin',
|
||||||
|
label: 'Garaža',
|
||||||
|
scale: 4.0,
|
||||||
|
colliderW: 200, colliderH: 80, colliderOffsetX: -100, colliderOffsetY: -40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'barn_ruin',
|
||||||
|
label: 'Hlev',
|
||||||
|
scale: 4.0,
|
||||||
|
colliderW: 200, colliderH: 80, colliderOffsetX: -100, colliderOffsetY: -40
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// === TAKOJ SPAWNI ZOMBIJA (za testiranje, podnevi+ponoči) ===
|
// === TAKOJ SPAWNI ZOMBIJA (za testiranje, podnevi+ponoči) ===
|
||||||
this.time.delayedCall(3000, () => {
|
this.time.delayedCall(3000, () => {
|
||||||
if (this.zombieSystem) {
|
if (this.zombieSystem) {
|
||||||
@@ -1525,8 +1622,10 @@ export default class GrassSceneClean extends Phaser.Scene {
|
|||||||
console.log("SFX: THUD!");
|
console.log("SFX: THUD!");
|
||||||
// this.sound.play('tree_thud');
|
// this.sound.play('tree_thud');
|
||||||
|
|
||||||
// Visual: Screen Shake
|
// Visual: Screen Shake (izklopljen v Autism Mode)
|
||||||
this.cameras.main.shake(300, 0.005);
|
if (!this.accessState?.autismMode) {
|
||||||
|
this.cameras.main.shake(300, 0.005);
|
||||||
|
}
|
||||||
|
|
||||||
tree.destroy();
|
tree.destroy();
|
||||||
|
|
||||||
@@ -1880,6 +1979,26 @@ export default class GrassSceneClean extends Phaser.Scene {
|
|||||||
/* Removed for cleanup */
|
/* Removed for cleanup */
|
||||||
|
|
||||||
update(time, delta) {
|
update(time, delta) {
|
||||||
|
if (this.kai && this.kai.active) {
|
||||||
|
// --- LOOKAHEAD CAMERA OFFSET (Gledanje naprej) ---
|
||||||
|
const maxOffset = 180; // Koliko pikslov naprej naj pogleda kamera
|
||||||
|
let targetOffsetX = 0;
|
||||||
|
let targetOffsetY = 0;
|
||||||
|
|
||||||
|
if (this.kai.body.velocity.x > 10) targetOffsetX = maxOffset;
|
||||||
|
else if (this.kai.body.velocity.x < -10) targetOffsetX = -maxOffset;
|
||||||
|
|
||||||
|
if (this.kai.body.velocity.y > 10) targetOffsetY = maxOffset;
|
||||||
|
else if (this.kai.body.velocity.y < -10) targetOffsetY = -maxOffset;
|
||||||
|
|
||||||
|
// Gladko lerpanje proti tarči offseta (manjša vrednost = bolj gladko)
|
||||||
|
this.cameraLookahead.x = Phaser.Math.Linear(this.cameraLookahead.x, targetOffsetX, 0.03);
|
||||||
|
this.cameraLookahead.y = Phaser.Math.Linear(this.cameraLookahead.y, targetOffsetY, 0.03);
|
||||||
|
|
||||||
|
// V Phaserju pozitiven offset zamakne *tarčo*, kar pomeni da gre kamera v drugo smer!
|
||||||
|
this.cameras.main.setFollowOffset(this.cameraLookahead.x, this.cameraLookahead.y);
|
||||||
|
}
|
||||||
|
|
||||||
// --- ANIMATE OCEAN ---
|
// --- ANIMATE OCEAN ---
|
||||||
// (Parallax skipped for rectangles, logic removed to prevent errors)
|
// (Parallax skipped for rectangles, logic removed to prevent errors)
|
||||||
// --- ANIMATE FOAM ---
|
// --- ANIMATE FOAM ---
|
||||||
@@ -1935,10 +2054,25 @@ export default class GrassSceneClean extends Phaser.Scene {
|
|||||||
const velocity = new Phaser.Math.Vector2(0, 0);
|
const velocity = new Phaser.Math.Vector2(0, 0);
|
||||||
|
|
||||||
// Input helpers
|
// Input helpers
|
||||||
const left = this.cursors.left.isDown || this.keys.left.isDown;
|
let left = this.cursors.left.isDown || this.keys.left.isDown;
|
||||||
const right = this.cursors.right.isDown || this.keys.right.isDown;
|
let right = this.cursors.right.isDown || this.keys.right.isDown;
|
||||||
const up = this.cursors.up.isDown || this.keys.up.isDown;
|
let up = this.cursors.up.isDown || this.keys.up.isDown;
|
||||||
const down = this.cursors.down.isDown || this.keys.down.isDown;
|
let down = this.cursors.down.isDown || this.keys.down.isDown;
|
||||||
|
|
||||||
|
// ── ENOROČNI NAČIN (Sledenje miški z držanjem klika) ──
|
||||||
|
if (this.accessState?.onehandMode && this.input.activePointer.isDown) {
|
||||||
|
const ptr = this.input.activePointer;
|
||||||
|
// Preprečimo tresenje, če je miška preblizu lika
|
||||||
|
if (Phaser.Math.Distance.Between(this.kai.x, this.kai.y - 30, ptr.worldX, ptr.worldY) > 25) {
|
||||||
|
const angle = Phaser.Math.Angle.Between(this.kai.x, this.kai.y - 30, ptr.worldX, ptr.worldY);
|
||||||
|
const dx = Math.cos(angle);
|
||||||
|
const dy = Math.sin(angle);
|
||||||
|
if (dx < -0.3) left = true;
|
||||||
|
if (dx > 0.3) right = true;
|
||||||
|
if (dy < -0.3) up = true;
|
||||||
|
if (dy > 0.3) down = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
const space = this.cursors.space.isDown;
|
const space = this.cursors.space.isDown;
|
||||||
|
|
||||||
if (left) velocity.x = -1;
|
if (left) velocity.x = -1;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* - Fog (megla) ki se premika
|
* - Fog (megla) ki se premika
|
||||||
* ============================================================
|
* ============================================================
|
||||||
*/
|
*/
|
||||||
|
import LocalizationSystem from '../systems/LocalizationSystem.js';
|
||||||
export default class MenuScene extends Phaser.Scene {
|
export default class MenuScene extends Phaser.Scene {
|
||||||
constructor() {
|
constructor() {
|
||||||
super({ key: 'MenuScene' });
|
super({ key: 'MenuScene' });
|
||||||
@@ -20,6 +21,9 @@ export default class MenuScene extends Phaser.Scene {
|
|||||||
preload() {
|
preload() {
|
||||||
this.load.path = 'assets/';
|
this.load.path = 'assets/';
|
||||||
|
|
||||||
|
// Naloži prevode
|
||||||
|
this.load.json('localization', 'localization.json');
|
||||||
|
|
||||||
// Ozadje
|
// Ozadje
|
||||||
this.load.image('menu_bg', 'DEMO_FAZA1/UI/menu_background.png');
|
this.load.image('menu_bg', 'DEMO_FAZA1/UI/menu_background.png');
|
||||||
|
|
||||||
@@ -38,6 +42,10 @@ export default class MenuScene extends Phaser.Scene {
|
|||||||
const W = this.cameras.main.width; // 1920
|
const W = this.cameras.main.width; // 1920
|
||||||
const H = this.cameras.main.height; // 1080
|
const H = this.cameras.main.height; // 1080
|
||||||
|
|
||||||
|
// ─── INITIALIZE LOCALIZATION ───
|
||||||
|
this.i18n = new LocalizationSystem(this);
|
||||||
|
this.i18n.init();
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────
|
||||||
// OZADJE
|
// OZADJE
|
||||||
// ─────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────
|
||||||
@@ -165,9 +173,10 @@ export default class MenuScene extends Phaser.Scene {
|
|||||||
const BTN_GAP = 95;
|
const BTN_GAP = 95;
|
||||||
|
|
||||||
const buttons = [
|
const buttons = [
|
||||||
{ label: '▶ IGRAJ', id: 'play', color: '#44ffcc', hColor: '#ffffff' },
|
{ label: '▶ ' + this.i18n.t('menu_play'), id: 'play', color: '#44ffcc', hColor: '#ffffff' },
|
||||||
{ label: '⚙ NASTAVITVE', id: 'settings', color: '#aabbcc', hColor: '#ffffff' },
|
{ label: '⚙ ' + this.i18n.t('menu_options'), id: 'settings', color: '#aabbcc', hColor: '#ffffff' },
|
||||||
{ label: '✕ IZHOD', id: 'quit', color: '#cc6666', hColor: '#ff8888' },
|
{ label: '🌍 ' + this.i18n.t('lang_btn'), id: 'lang', color: '#ccddaa', hColor: '#ffffff' },
|
||||||
|
{ label: '✕ ' + this.i18n.t('menu_exit'), id: 'quit', color: '#cc6666', hColor: '#ff8888' },
|
||||||
];
|
];
|
||||||
|
|
||||||
this._btns = [];
|
this._btns = [];
|
||||||
@@ -188,7 +197,7 @@ export default class MenuScene extends Phaser.Scene {
|
|||||||
|
|
||||||
// Gumb tekst
|
// Gumb tekst
|
||||||
const txt = this.add.text(BTN_X, y, b.label, {
|
const txt = this.add.text(BTN_X, y, b.label, {
|
||||||
fontFamily: '"Arial Black", Arial',
|
fontFamily: this.i18n.fontFamily,
|
||||||
fontSize: '26px',
|
fontSize: '26px',
|
||||||
color: b.color,
|
color: b.color,
|
||||||
stroke: '#000000',
|
stroke: '#000000',
|
||||||
@@ -284,6 +293,15 @@ export default class MenuScene extends Phaser.Scene {
|
|||||||
// TODO: SettingsScene
|
// TODO: SettingsScene
|
||||||
this._showToast('Nastavitve kmalu! 🔧');
|
this._showToast('Nastavitve kmalu! 🔧');
|
||||||
}
|
}
|
||||||
|
else if (id === 'lang') {
|
||||||
|
// Cycle language
|
||||||
|
const langs = this.i18n.supportedLangs;
|
||||||
|
let idx = langs.indexOf(this.i18n.currentLang);
|
||||||
|
idx = (idx + 1) % langs.length;
|
||||||
|
this.i18n.setLanguage(langs[idx]);
|
||||||
|
// Restart scene to apply new language
|
||||||
|
this.scene.restart();
|
||||||
|
}
|
||||||
else if (id === 'quit') {
|
else if (id === 'quit') {
|
||||||
// Electron quit
|
// Electron quit
|
||||||
if (typeof window !== 'undefined' && window.electronAPI) {
|
if (typeof window !== 'undefined' && window.electronAPI) {
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
* OVERLAY: Health Critical pulse (pri < 25% HP)
|
* OVERLAY: Health Critical pulse (pri < 25% HP)
|
||||||
* =============================================================
|
* =============================================================
|
||||||
*/
|
*/
|
||||||
|
import LocalizationSystem from '../systems/LocalizationSystem.js';
|
||||||
|
import AccessibilityManager from '../systems/AccessibilityManager.js';
|
||||||
|
|
||||||
export default class UIScene extends Phaser.Scene {
|
export default class UIScene extends Phaser.Scene {
|
||||||
constructor() {
|
constructor() {
|
||||||
super({ key: 'UIScene', active: false }); // Zaženemo ročno iz GrassScene
|
super({ key: 'UIScene', active: false }); // Zaženemo ročno iz GrassScene
|
||||||
@@ -31,6 +34,11 @@ export default class UIScene extends Phaser.Scene {
|
|||||||
inventoryOpen: false,
|
inventoryOpen: false,
|
||||||
hotbarItems: [null, null, null, null, null, null, null], // 7 slotov
|
hotbarItems: [null, null, null, null, null, null, null], // 7 slotov
|
||||||
activeSlot: 0,
|
activeSlot: 0,
|
||||||
|
isFullGame: false,
|
||||||
|
accessibility: {
|
||||||
|
deafMode: false, autismMode: false, adhdMode: false,
|
||||||
|
fontMode: false, contrastMode: false, colorblindMode: false, onehandMode: false
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +64,10 @@ export default class UIScene extends Phaser.Scene {
|
|||||||
const H = this.cameras.main.height; // 1080
|
const H = this.cameras.main.height; // 1080
|
||||||
const PAD = 24;
|
const PAD = 24;
|
||||||
|
|
||||||
|
// ─── INITIALIZE LOCALIZATION ───
|
||||||
|
this.i18n = new LocalizationSystem(this);
|
||||||
|
this.i18n.init();
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────
|
||||||
// TOP LEFT — Trial badge + HP + Energy
|
// TOP LEFT — Trial badge + HP + Energy
|
||||||
// ─────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────
|
||||||
@@ -76,6 +88,14 @@ export default class UIScene extends Phaser.Scene {
|
|||||||
ease: 'Sine.easeInOut',
|
ease: 'Sine.easeInOut',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ── NAKUP IGRE LOGIKA ──
|
||||||
|
this.trialBadge.setInteractive({ useHandCursor: true });
|
||||||
|
this.trialBadge.on('pointerdown', () => {
|
||||||
|
if (!this.gameState.isFullGame) {
|
||||||
|
this.unlockFullGame();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// ── HP Bar (health_bar.png je vertikalni triptih: full/empty/empty) ─
|
// ── HP Bar (health_bar.png je vertikalni triptih: full/empty/empty) ─
|
||||||
// Spritesheet je 3 vrstice: top=HP full, mid=HP empty, bot=Energy
|
// Spritesheet je 3 vrstice: top=HP full, mid=HP empty, bot=Energy
|
||||||
// Uporabljamo health_bar.png kot ozadje in rišemo fill čez njega
|
// Uporabljamo health_bar.png kot ozadje in rišemo fill čez njega
|
||||||
@@ -135,6 +155,23 @@ export default class UIScene extends Phaser.Scene {
|
|||||||
// Prvič nariši
|
// Prvič nariši
|
||||||
this._redrawBars();
|
this._redrawBars();
|
||||||
|
|
||||||
|
// ── ACCESSIBILITY MENU BUTTON ──
|
||||||
|
this.accBtn = this.add.text(W - PAD, PAD + 180, '⚙️ ' + this.i18n.t('acc_menu'), {
|
||||||
|
fontFamily: this.i18n.fontFamily,
|
||||||
|
fontSize: '18px',
|
||||||
|
color: '#ffffff',
|
||||||
|
backgroundColor: '#000000aa',
|
||||||
|
padding: { x: 10, y: 5 },
|
||||||
|
stroke: '#ff00ff',
|
||||||
|
strokeThickness: 2
|
||||||
|
}).setOrigin(1, 0).setInteractive({ useHandCursor: true }).setDepth(1000);
|
||||||
|
|
||||||
|
// ── INIT ACCESSIBILITY MANAGER ──
|
||||||
|
this.accManager = new AccessibilityManager(this);
|
||||||
|
this.accManager.setupMenu(W, H);
|
||||||
|
|
||||||
|
this.accBtn.on('pointerdown', () => this.accManager.toggleMenu());
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────
|
||||||
// TOP RIGHT — Weather Widget (ura + vreme)
|
// TOP RIGHT — Weather Widget (ura + vreme)
|
||||||
// ─────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────
|
||||||
@@ -153,8 +190,8 @@ export default class UIScene extends Phaser.Scene {
|
|||||||
}).setOrigin(0.5, 0.5).setDepth(1005);
|
}).setOrigin(0.5, 0.5).setDepth(1005);
|
||||||
|
|
||||||
// Dan label (pod uro)
|
// Dan label (pod uro)
|
||||||
this.dayText = this.add.text(W - PAD - 135, PAD + 10, 'DAN 1', {
|
this.dayText = this.add.text(W - PAD - 135, PAD + 10, this.i18n.t('day') + ' 1', {
|
||||||
fontFamily: 'Arial Black',
|
fontFamily: this.i18n.fontFamily,
|
||||||
fontSize: '18px',
|
fontSize: '18px',
|
||||||
color: '#ffdd44',
|
color: '#ffdd44',
|
||||||
stroke: '#000000',
|
stroke: '#000000',
|
||||||
@@ -217,8 +254,8 @@ export default class UIScene extends Phaser.Scene {
|
|||||||
this.actionBtn.on('pointerout', () => this.actionBtn.clearTint());
|
this.actionBtn.on('pointerout', () => this.actionBtn.clearTint());
|
||||||
|
|
||||||
// Crafting label
|
// Crafting label
|
||||||
this.add.text(this.actionBtn.x, H - PAD + 2, 'CRAFTING', {
|
this.add.text(this.actionBtn.x, H - PAD + 2, this.i18n.t('crafting'), {
|
||||||
fontFamily: 'Arial',
|
fontFamily: this.i18n.fontFamily,
|
||||||
fontSize: '13px',
|
fontSize: '13px',
|
||||||
color: '#aaaaaa',
|
color: '#aaaaaa',
|
||||||
stroke: '#000',
|
stroke: '#000',
|
||||||
@@ -254,8 +291,8 @@ export default class UIScene extends Phaser.Scene {
|
|||||||
this._mmR = MM_SIZE / 2 - 16;
|
this._mmR = MM_SIZE / 2 - 16;
|
||||||
|
|
||||||
// "MAP" label
|
// "MAP" label
|
||||||
this.add.text(mmCx, mmCy + MM_SIZE / 2 - 8, 'MAPA', {
|
this.add.text(mmCx, mmCy + MM_SIZE / 2 - 8, this.i18n.t('map'), {
|
||||||
fontFamily: 'Arial',
|
fontFamily: this.i18n.fontFamily,
|
||||||
fontSize: '11px',
|
fontSize: '11px',
|
||||||
color: '#556655',
|
color: '#556655',
|
||||||
}).setOrigin(0.5, 1).setDepth(1002);
|
}).setOrigin(0.5, 1).setDepth(1002);
|
||||||
@@ -643,4 +680,96 @@ export default class UIScene extends Phaser.Scene {
|
|||||||
this.minimapKaiDot.lineStyle(2, 0xffffff, 0.6);
|
this.minimapKaiDot.lineStyle(2, 0xffffff, 0.6);
|
||||||
this.minimapKaiDot.strokeCircle(dotX, dotY, 7);
|
this.minimapKaiDot.strokeCircle(dotX, dotY, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =========================================================
|
||||||
|
// FULL GAME UNLOCK
|
||||||
|
// =========================================================
|
||||||
|
unlockFullGame() {
|
||||||
|
this.gameState.isFullGame = true;
|
||||||
|
|
||||||
|
// Zamenjaj badge
|
||||||
|
this.trialBadge.setTexture('ui_badge_buy');
|
||||||
|
this.trialBadge.clearTint();
|
||||||
|
|
||||||
|
// Dark-Chibi Noir UI stil: Velik napis preko ekrana
|
||||||
|
const W = this.cameras.main.width;
|
||||||
|
const H = this.cameras.main.height;
|
||||||
|
let unlockText = this.add.text(W / 2, H / 2, 'ODKLENJENO\nFULL GAME', {
|
||||||
|
fontFamily: 'Arial Black',
|
||||||
|
fontSize: '72px',
|
||||||
|
color: '#44ffaa',
|
||||||
|
stroke: '#000000',
|
||||||
|
strokeThickness: 10,
|
||||||
|
align: 'center'
|
||||||
|
}).setOrigin(0.5, 0.5).setDepth(9999).setAlpha(0);
|
||||||
|
|
||||||
|
// Zatemnitev ozadja
|
||||||
|
let dim = this.add.rectangle(W/2, H/2, W, H, 0x000000, 0.6)
|
||||||
|
.setDepth(9998).setAlpha(0);
|
||||||
|
|
||||||
|
this.tweens.add({
|
||||||
|
targets: [unlockText, dim],
|
||||||
|
alpha: 1,
|
||||||
|
duration: 1500,
|
||||||
|
ease: 'Power2',
|
||||||
|
yoyo: true,
|
||||||
|
hold: 3000,
|
||||||
|
onComplete: () => {
|
||||||
|
unlockText.destroy();
|
||||||
|
dim.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Pošlji signal v GrassScene, da se odklene Faza 1
|
||||||
|
this.game.events.emit('unlock-faza1');
|
||||||
|
}
|
||||||
|
|
||||||
|
// =========================================================
|
||||||
|
// ADHD MODE TOGGLE
|
||||||
|
// =========================================================
|
||||||
|
toggleADHDMode(isOn) {
|
||||||
|
let alpha = isOn ? 0.0 : 1.0; // Popolnoma skrij ali prikaži
|
||||||
|
|
||||||
|
// Vse elemente, ki niso nujni, skrijemo
|
||||||
|
const hideEls = [
|
||||||
|
this.weatherWidget, this.timeText, this.dayText,
|
||||||
|
this.trialBadge, this.hpBg, this.hpFill, this.hpText,
|
||||||
|
this.energyBg, this.energyFill, this.energyText,
|
||||||
|
this.hotbarBg, this.actionBtn,
|
||||||
|
this.minimapFrame, this.minimapBg, this.minimapKaiDot
|
||||||
|
// this.accBtn namerno ni tukaj, da ga igralec še vedno lahko klikne in ugasne mode!
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const el of hideEls) {
|
||||||
|
if (el) el.setAlpha(alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skrij tudi hotbar slot elemente
|
||||||
|
if (this.hotbarSlots) {
|
||||||
|
for (const slot of this.hotbarSlots) {
|
||||||
|
if (slot.numLabel) slot.numLabel.setAlpha(alpha);
|
||||||
|
if (slot.highlight) slot.highlight.setAlpha(alpha);
|
||||||
|
if (slot.itemSprite) slot.itemSprite.setAlpha(alpha);
|
||||||
|
if (slot.qtyText) slot.qtyText.setAlpha(alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prikaži velik utripajoč cilj
|
||||||
|
if (isOn && !this.adhdGoal) {
|
||||||
|
const W = this.cameras.main.width;
|
||||||
|
this.adhdGoal = this.add.text(W / 2, 100, this.i18n.t('adhd_goal'), {
|
||||||
|
fontFamily: this.i18n.fontFamily, fontSize: '32px', color: '#ffff00', backgroundColor: '#000000aa', padding: { x: 20, y: 10 }, stroke: '#000', strokeThickness: 6
|
||||||
|
}).setOrigin(0.5).setDepth(9998);
|
||||||
|
this.tweens.add({ targets: this.adhdGoal, alpha: 0.3, duration: 800, yoyo: true, repeat: -1 });
|
||||||
|
} else if (!isOn && this.adhdGoal) {
|
||||||
|
this.adhdGoal.destroy();
|
||||||
|
this.adhdGoal = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update(time, delta) {
|
||||||
|
if (this.accManager) {
|
||||||
|
this.accManager.update(time, delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
190
nova farma TRAE/src/systems/AccessibilityManager.js
Normal file
190
nova farma TRAE/src/systems/AccessibilityManager.js
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
/**
|
||||||
|
* AccessibilityManager.js
|
||||||
|
*
|
||||||
|
* Vodi celoten Accessibility Meni ter vizualna opozorila za Deaf Mode.
|
||||||
|
*/
|
||||||
|
export default class AccessibilityManager {
|
||||||
|
constructor(scene) {
|
||||||
|
this.scene = scene; // UIScene
|
||||||
|
this.deafAlertRed = null;
|
||||||
|
this.twinBondGlow = null;
|
||||||
|
this.glitchOverlay = null;
|
||||||
|
|
||||||
|
// Poslušaj evente
|
||||||
|
if (this.scene.game) {
|
||||||
|
this.scene.game.events.on('twinBondPulse', this.triggerTwinBondGlow, this);
|
||||||
|
this.scene.game.events.on('flashbackPulse', this.triggerFlashbackGlitch, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nastavi celoten meni (klicano iz UIScene)
|
||||||
|
setupMenu(W, H) {
|
||||||
|
this.accMenuContainer = this.scene.add.container(W / 2, H / 2).setDepth(9999).setVisible(false);
|
||||||
|
|
||||||
|
let bg = this.scene.add.rectangle(0, 0, 800, 500, 0x111111, 0.95).setStrokeStyle(4, 0xff00ff);
|
||||||
|
let title = this.scene.add.text(0, -210, this.scene.i18n.t('acc_menu'), {
|
||||||
|
fontFamily: this.scene.i18n.fontFamily, fontSize: '24px', color: '#ffdd00'
|
||||||
|
}).setOrigin(0.5);
|
||||||
|
|
||||||
|
// STOLPEC 1
|
||||||
|
let btn1 = this.createAccButton(-190, -110, this.scene.i18n.t('acc_deaf'), 'deafMode');
|
||||||
|
let btn2 = this.createAccButton(-190, -40, this.scene.i18n.t('acc_autism'), 'autismMode');
|
||||||
|
let btn3 = this.createAccButton(-190, 30, this.scene.i18n.t('acc_adhd'), 'adhdMode');
|
||||||
|
let btn4 = this.createAccButton(-190, 100, this.scene.i18n.t('acc_onehand'), 'onehandMode');
|
||||||
|
|
||||||
|
// STOLPEC 2
|
||||||
|
let btn5 = this.createAccButton(190, -110, this.scene.i18n.t('acc_font'), 'fontMode');
|
||||||
|
let btn6 = this.createAccButton(190, -40, this.scene.i18n.t('acc_contrast'), 'contrastMode');
|
||||||
|
let btn7 = this.createAccButton(190, 30, this.scene.i18n.t('acc_colorblind'), 'colorblindMode');
|
||||||
|
|
||||||
|
let closeBtn = this.scene.add.text(0, 200, this.scene.i18n.t('acc_close'), { fontFamily: this.scene.i18n.fontFamily, fontSize: '20px', color: '#ff4444' })
|
||||||
|
.setOrigin(0.5).setInteractive({ useHandCursor: true });
|
||||||
|
closeBtn.on('pointerdown', () => this.toggleMenu());
|
||||||
|
|
||||||
|
this.accMenuContainer.add([bg, title, btn1, btn2, btn3, btn4, btn5, btn6, btn7, closeBtn]);
|
||||||
|
}
|
||||||
|
|
||||||
|
createAccButton(x, y, text, key) {
|
||||||
|
let container = this.scene.add.container(x, y);
|
||||||
|
let bg = this.scene.add.rectangle(0, 0, 360, 50, 0x222222).setInteractive({ useHandCursor: true });
|
||||||
|
let txt = this.scene.add.text(0, 0, text + ' [OFF]', { fontFamily: this.scene.i18n.fontFamily, fontSize: '15px', color: '#aaaaaa' }).setOrigin(0.5);
|
||||||
|
|
||||||
|
bg.on('pointerdown', () => {
|
||||||
|
this.scene.gameState.accessibility[key] = !this.scene.gameState.accessibility[key];
|
||||||
|
let isOn = this.scene.gameState.accessibility[key];
|
||||||
|
bg.fillColor = isOn ? 0x004400 : 0x222222;
|
||||||
|
txt.setColor(isOn ? '#44ff44' : '#aaaaaa');
|
||||||
|
txt.setText(text + (isOn ? ' [ON]' : ' [OFF]'));
|
||||||
|
|
||||||
|
this.scene.game.events.emit('accessibility-changed', this.scene.gameState.accessibility);
|
||||||
|
|
||||||
|
// Apply specific immediate effects
|
||||||
|
if (key === 'adhdMode') this.scene.toggleADHDMode(isOn);
|
||||||
|
if (key === 'contrastMode' || key === 'colorblindMode') this.updateCanvasFilters();
|
||||||
|
if (key === 'fontMode') this.toggleLargeFont(isOn);
|
||||||
|
});
|
||||||
|
|
||||||
|
container.add([bg, txt]);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCanvasFilters() {
|
||||||
|
const isContrast = this.scene.gameState.accessibility.contrastMode;
|
||||||
|
const isColorblind = this.scene.gameState.accessibility.colorblindMode;
|
||||||
|
|
||||||
|
let filters = [];
|
||||||
|
if (isContrast) filters.push('contrast(1.5) drop-shadow(0 0 10px rgba(0,0,0,0.8))');
|
||||||
|
if (isColorblind) filters.push('saturate(1.5) sepia(0.3) hue-rotate(15deg)'); // Simple protanopia filter tweak
|
||||||
|
|
||||||
|
const canvas = document.querySelector('canvas');
|
||||||
|
if (canvas) {
|
||||||
|
canvas.style.filter = filters.length > 0 ? filters.join(' ') : 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleLargeFont(isOn) {
|
||||||
|
// Enostavna povečava vseh tekstov v UI (če je true, x1.2)
|
||||||
|
const scale = isOn ? 1.25 : 1.0;
|
||||||
|
this.scene.children.list.forEach(child => {
|
||||||
|
if (child.type === 'Text' && child !== this.accMenuContainer) {
|
||||||
|
this.scene.tweens.add({ targets: child, scaleX: scale, scaleY: scale, duration: 200 });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Tudi v GrassScene
|
||||||
|
const grass = this.scene.scene.get('GrassScene');
|
||||||
|
if (grass) {
|
||||||
|
grass.children.list.forEach(child => {
|
||||||
|
if (child.type === 'Text') {
|
||||||
|
grass.tweens.add({ targets: child, scaleX: scale, scaleY: scale, duration: 200 });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleMenu() {
|
||||||
|
if (this.accMenuContainer) {
|
||||||
|
this.accMenuContainer.setVisible(!this.accMenuContainer.visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Klicano v UIScene update
|
||||||
|
update(time, delta) {
|
||||||
|
const deafModeActive = this.scene.gameState.accessibility.deafMode;
|
||||||
|
|
||||||
|
if (!deafModeActive) {
|
||||||
|
if (this.deafAlertRed) { this.deafAlertRed.destroy(); this.deafAlertRed = null; }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Nevarnost zombijev
|
||||||
|
const grass = this.scene.scene.get('GrassScene');
|
||||||
|
if (grass && grass.zombieSystem && grass.kai) {
|
||||||
|
const zombies = grass.zombieSystem.getZombies();
|
||||||
|
let near = false;
|
||||||
|
for (const z of zombies) {
|
||||||
|
if (!z.tamed && Phaser.Math.Distance.Between(z.x, z.y, grass.kai.x, grass.kai.y) < 550) {
|
||||||
|
near = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (near) {
|
||||||
|
if (!this.deafAlertRed) {
|
||||||
|
const W = this.scene.cameras.main.width;
|
||||||
|
const H = this.scene.cameras.main.height;
|
||||||
|
this.deafAlertRed = this.scene.add.rectangle(W/2, H/2, W, H).setStrokeStyle(30, 0xff0000).setDepth(9999);
|
||||||
|
this.deafAlertRed.isFilled = false;
|
||||||
|
this.scene.tweens.add({ targets: this.deafAlertRed, alpha: 0.2, duration: 400, yoyo: true, repeat: -1 });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.deafAlertRed) { this.deafAlertRed.destroy(); this.deafAlertRed = null; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Twin Bond Glow
|
||||||
|
triggerTwinBondGlow() {
|
||||||
|
if (!this.scene.gameState.accessibility.deafMode) return;
|
||||||
|
if (this.twinBondGlow) { this.twinBondGlow.destroy(); }
|
||||||
|
|
||||||
|
const W = this.scene.cameras.main.width;
|
||||||
|
const H = this.scene.cameras.main.height;
|
||||||
|
this.twinBondGlow = this.scene.add.rectangle(W/2, H/2, W, H, 0xaa00ff, 0.4)
|
||||||
|
.setDepth(9998)
|
||||||
|
.setBlendMode(Phaser.BlendModes.SCREEN);
|
||||||
|
|
||||||
|
this.scene.tweens.add({
|
||||||
|
targets: this.twinBondGlow,
|
||||||
|
alpha: 0,
|
||||||
|
duration: 2000,
|
||||||
|
ease: 'Sine.inOut',
|
||||||
|
onComplete: () => {
|
||||||
|
if (this.twinBondGlow) { this.twinBondGlow.destroy(); this.twinBondGlow = null; }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Amnezija Spomini (Flashback glitch)
|
||||||
|
triggerFlashbackGlitch() {
|
||||||
|
if (!this.scene.gameState.accessibility.deafMode) return;
|
||||||
|
if (this.glitchOverlay) { this.glitchOverlay.destroy(); }
|
||||||
|
|
||||||
|
const W = this.scene.cameras.main.width;
|
||||||
|
const H = this.scene.cameras.main.height;
|
||||||
|
|
||||||
|
// Screen pulse / flash za flashback
|
||||||
|
this.glitchOverlay = this.scene.add.rectangle(W/2, H/2, W, H, 0xffffff, 0.9).setDepth(10000);
|
||||||
|
|
||||||
|
// Močan tresljaj kamere
|
||||||
|
this.scene.cameras.main.shake(300, 0.03);
|
||||||
|
|
||||||
|
this.scene.tweens.add({
|
||||||
|
targets: this.glitchOverlay,
|
||||||
|
alpha: 0,
|
||||||
|
duration: 400,
|
||||||
|
ease: 'Bounce.out',
|
||||||
|
onComplete: () => {
|
||||||
|
if (this.glitchOverlay) { this.glitchOverlay.destroy(); this.glitchOverlay = null; }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,9 +36,8 @@ export default class DayNightSystem {
|
|||||||
this.hour = 6; // Začne ob 6:00
|
this.hour = 6; // Začne ob 6:00
|
||||||
this.minute = 0;
|
this.minute = 0;
|
||||||
|
|
||||||
// Hitrost: 1 real sekunda = N minut v igri
|
// Hitrost: 1.2 igra minut = 1 real sekunda (24 ur v igri = 1200 real sekund = 20 minut)
|
||||||
// Default: 24 real minut = 1 dan → 1 real sec = 1 igra minuta
|
this.gameMinutesPerRealSecond = options.speed || 1.2;
|
||||||
this.gameMinutesPerRealSecond = options.speed || 1;
|
|
||||||
|
|
||||||
// Interaktivni objekti za spanje
|
// Interaktivni objekti za spanje
|
||||||
this.sleepObjects = []; // { x, y, sprite, type }
|
this.sleepObjects = []; // { x, y, sprite, type }
|
||||||
@@ -124,6 +123,11 @@ export default class DayNightSystem {
|
|||||||
this._onMidnight();
|
this._onMidnight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Kazen za nespametne: Omedli ob 02:00, če še ne spi
|
||||||
|
if (this.hour === 2 && this.minute === 0 && !this.isSleeping) {
|
||||||
|
this.passOut();
|
||||||
|
}
|
||||||
|
|
||||||
// Emit UI update vsako minuto
|
// Emit UI update vsako minuto
|
||||||
this.scene.events.emit('timeChanged', {
|
this.scene.events.emit('timeChanged', {
|
||||||
day: this.day,
|
day: this.day,
|
||||||
@@ -226,6 +230,63 @@ export default class DayNightSystem {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────────────────────────────────
|
||||||
|
// PASS OUT — Omedli ob 02:00 (Kazen)
|
||||||
|
// ─────────────────────────────────────────────────────────────────────────
|
||||||
|
passOut() {
|
||||||
|
if (this.isSleeping) return;
|
||||||
|
this.isSleeping = true;
|
||||||
|
console.log(`💀 KAI JE OMEDLEL OD UTRUJENOSTI (02:00)!`);
|
||||||
|
|
||||||
|
// Zatemnitev zaslona in rdeč napis
|
||||||
|
this.scene.cameras.main.fadeOut(1500, 20, 0, 0);
|
||||||
|
|
||||||
|
const cx = this.scene.cameras.main.centerX;
|
||||||
|
const cy = this.scene.cameras.main.centerY;
|
||||||
|
|
||||||
|
let passOutText = this.scene.add.text(cx, cy, 'OMEDLEL SI\n(Kazen: -Energija, -Denar)', {
|
||||||
|
fontFamily: 'Arial Black',
|
||||||
|
fontSize: '48px',
|
||||||
|
color: '#ff2222',
|
||||||
|
stroke: '#000000',
|
||||||
|
strokeThickness: 8,
|
||||||
|
align: 'center'
|
||||||
|
}).setOrigin(0.5, 0.5).setDepth(9999).setScrollFactor(0);
|
||||||
|
|
||||||
|
this.scene.time.delayedCall(2000, () => {
|
||||||
|
// Skok na jutro
|
||||||
|
this.hour = 6;
|
||||||
|
this.minute = 0;
|
||||||
|
|
||||||
|
// Kazni
|
||||||
|
if (this.scene.gameState) {
|
||||||
|
this.scene.gameState.energy = Math.max(10, this.scene.gameState.energy - 50); // Zelo malo energije ostane
|
||||||
|
this.scene.events.emit('ui-update-energy', this.scene.gameState.energy);
|
||||||
|
}
|
||||||
|
if (this.scene.playerGold !== undefined) {
|
||||||
|
this.scene.playerGold = Math.max(0, this.scene.playerGold - 50); // Izgubi 50g
|
||||||
|
const uiScene = this.scene.scene.get('UIScene');
|
||||||
|
if (uiScene && uiScene.events) uiScene.events.emit('goldChanged', this.scene.playerGold);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit morning events
|
||||||
|
this.scene.events.emit('morningArrived', { day: this.day });
|
||||||
|
this.scene.events.emit('timeChanged', {
|
||||||
|
day: this.day, hour: 6, minute: 0, timeStr: '06:00'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Odstrani tekst in fade in
|
||||||
|
passOutText.destroy();
|
||||||
|
this.scene.cameras.main.fadeIn(1500, 0, 0, 0);
|
||||||
|
|
||||||
|
this._showDayOverlay(this.day);
|
||||||
|
|
||||||
|
this.scene.time.delayedCall(1600, () => {
|
||||||
|
this.isSleeping = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────────
|
||||||
// AMBIENT OSVETLITEV
|
// AMBIENT OSVETLITEV
|
||||||
// ─────────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────────
|
||||||
@@ -256,14 +317,14 @@ export default class DayNightSystem {
|
|||||||
alpha = 0.35 + t * 0.25;
|
alpha = 0.35 + t * 0.25;
|
||||||
r = 0x00; g = 0x00; b = 0x44;
|
r = 0x00; g = 0x00; b = 0x44;
|
||||||
} else if (h >= 22 || h < 4) {
|
} else if (h >= 22 || h < 4) {
|
||||||
// Noč: globoka modra tema
|
// Noč: globoka modra tema (Dark-Chibi Noir Stil)
|
||||||
alpha = 0.60;
|
alpha = 0.85; // Zelo mračno, nevarno
|
||||||
r = 0x00; g = 0x00; b = 0x22;
|
r = 0x01; g = 0x01; b = 0x08; // Črna / globoko temno modra
|
||||||
} else if (h >= 4 && h < 6) {
|
} else if (h >= 4 && h < 6) {
|
||||||
// Pred zoro
|
// Pred zoro
|
||||||
const t = (h - 4) / 2;
|
const t = (h - 4) / 2;
|
||||||
alpha = 0.60 * (1 - t * 0.5);
|
alpha = 0.85 * (1 - t * 0.5);
|
||||||
r = 0x00; g = 0x00; b = 0x22;
|
r = 0x01; g = 0x01; b = 0x08;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ambientOverlay.clear();
|
this.ambientOverlay.clear();
|
||||||
|
|||||||
72
nova farma TRAE/src/systems/LocalizationSystem.js
Normal file
72
nova farma TRAE/src/systems/LocalizationSystem.js
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* LocalizationSystem.js
|
||||||
|
*
|
||||||
|
* Sistem za jezike: SL (privzeto), EN, DE, IT, CN.
|
||||||
|
* Samodejno zazna OS jezik.
|
||||||
|
*/
|
||||||
|
export default class LocalizationSystem {
|
||||||
|
constructor(scene) {
|
||||||
|
this.scene = scene;
|
||||||
|
this.supportedLangs = ['sl', 'en', 'de', 'it', 'cn'];
|
||||||
|
this.currentLang = 'sl';
|
||||||
|
this.translations = {};
|
||||||
|
|
||||||
|
// UTF-8 pisava s podporo za šumnike in kitajske pismenke
|
||||||
|
this.fontFamily = '"Noto Sans", "Noto Sans SC", "Arial Black", sans-serif';
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
// Preveri če imamo shranjen jezik
|
||||||
|
const savedLang = localStorage.getItem('nova_farma_lang');
|
||||||
|
if (savedLang && this.supportedLangs.includes(savedLang)) {
|
||||||
|
this.currentLang = savedLang;
|
||||||
|
console.log(`🌍 Localization: Loaded saved lang: ${this.currentLang}`);
|
||||||
|
} else {
|
||||||
|
// Zaznaj sistemski jezik igralca
|
||||||
|
const sysLang = navigator.language || navigator.userLanguage;
|
||||||
|
let shortLang = sysLang.split('-')[0].toLowerCase();
|
||||||
|
|
||||||
|
// Preslikava zh -> cn
|
||||||
|
if (shortLang === 'zh') shortLang = 'cn';
|
||||||
|
|
||||||
|
if (this.supportedLangs.includes(shortLang)) {
|
||||||
|
this.currentLang = shortLang;
|
||||||
|
} else {
|
||||||
|
// Če jezika ni podprtega, se vrni na privzeto Slovenščino (po navodilu)
|
||||||
|
this.currentLang = 'sl';
|
||||||
|
}
|
||||||
|
console.log(`🌍 Localization: Detected OS lang: ${sysLang}, using: ${this.currentLang}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Naloži JSON slovar iz Phaserjevega Cache-a
|
||||||
|
if (this.scene.cache.json.exists('localization')) {
|
||||||
|
this.translations = this.scene.cache.json.get('localization');
|
||||||
|
} else {
|
||||||
|
console.warn('⚠️ localization.json ni naložen v cache!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setLanguage(lang) {
|
||||||
|
if (this.supportedLangs.includes(lang)) {
|
||||||
|
this.currentLang = lang;
|
||||||
|
localStorage.setItem('nova_farma_lang', lang);
|
||||||
|
|
||||||
|
// Če želimo emitirati po celem game-u
|
||||||
|
if (this.scene && this.scene.game) {
|
||||||
|
this.scene.game.events.emit('language-changed', this.currentLang);
|
||||||
|
}
|
||||||
|
console.log(`🌍 Jezik spremenjen na: ${this.currentLang}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t(key) {
|
||||||
|
if (this.translations[this.currentLang] && this.translations[this.currentLang][key]) {
|
||||||
|
return this.translations[this.currentLang][key];
|
||||||
|
}
|
||||||
|
// Fallback na slovenščino
|
||||||
|
if (this.translations['sl'] && this.translations['sl'][key]) {
|
||||||
|
return this.translations['sl'][key];
|
||||||
|
}
|
||||||
|
return `[${key}]`; // Če ključa sploh ni
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,6 +62,11 @@ export default class TwinBondSystem {
|
|||||||
|
|
||||||
triggerBond() {
|
triggerBond() {
|
||||||
this.isActive = true;
|
this.isActive = true;
|
||||||
|
|
||||||
|
// Oddaj event za AccessibilityManager (za Deaf Mode Purple HUD glow)
|
||||||
|
if (this.scene.game) {
|
||||||
|
this.scene.game.events.emit('twinBondPulse');
|
||||||
|
}
|
||||||
|
|
||||||
// Zaustavi Kaja za kratek čas (šok)
|
// Zaustavi Kaja za kratek čas (šok)
|
||||||
if (this.scene.kai) {
|
if (this.scene.kai) {
|
||||||
@@ -76,7 +81,9 @@ export default class TwinBondSystem {
|
|||||||
const W = this.scene.cameras.main.width;
|
const W = this.scene.cameras.main.width;
|
||||||
const H = this.scene.cameras.main.height;
|
const H = this.scene.cameras.main.height;
|
||||||
this.flashOverlay.clear();
|
this.flashOverlay.clear();
|
||||||
this.flashOverlay.fillStyle(0x3a0055, 0.85); // Temno vijolična
|
|
||||||
|
let alpha = this.scene.accessState?.autismMode ? 0.2 : 0.85; // Omehčan za avtizem
|
||||||
|
this.flashOverlay.fillStyle(0x3a0055, alpha); // Temno vijolična
|
||||||
this.flashOverlay.fillRect(0, 0, W, H);
|
this.flashOverlay.fillRect(0, 0, W, H);
|
||||||
|
|
||||||
// Skrijemo čez 0.15s
|
// Skrijemo čez 0.15s
|
||||||
|
|||||||
@@ -99,9 +99,10 @@ export default class ZombieSystem {
|
|||||||
this._nightCount++;
|
this._nightCount++;
|
||||||
|
|
||||||
// Stopnjevanje tezje po vsaki noci
|
// Stopnjevanje tezje po vsaki noci
|
||||||
this.maxZombies = Math.min(2 + this._nightCount, 8);
|
// Povečana nevarnost: 2x močnejši, večja hitrost in večje število
|
||||||
const spawnDelay = Math.max(6000, 14000 - this._nightCount * 1000);
|
this.maxZombies = Math.min(4 + this._nightCount * 2, 16);
|
||||||
this.zombieSpeed = Math.min(35 + this._nightCount * 3, 65);
|
const spawnDelay = Math.max(3000, 8000 - this._nightCount * 1000);
|
||||||
|
this.zombieSpeed = Math.min(60 + this._nightCount * 5, 100);
|
||||||
|
|
||||||
console.log(`🌙 Noč ${this._nightCount}: max=${this.maxZombies}, delay=${spawnDelay}ms, speed=${this.zombieSpeed}px/s`);
|
console.log(`🌙 Noč ${this._nightCount}: max=${this.maxZombies}, delay=${spawnDelay}ms, speed=${this.zombieSpeed}px/s`);
|
||||||
|
|
||||||
@@ -112,6 +113,10 @@ export default class ZombieSystem {
|
|||||||
if (this.zombies.length < this.maxZombies) {
|
if (this.zombies.length < this.maxZombies) {
|
||||||
this.spawnZombie();
|
this.spawnZombie();
|
||||||
}
|
}
|
||||||
|
// Samo ponoči: 30% možnost za spawn Rakuna na robu mape
|
||||||
|
if (Math.random() < 0.3) {
|
||||||
|
this.spawnRaccoon();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -205,6 +210,49 @@ export default class ZombieSystem {
|
|||||||
return zombie;
|
return zombie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────────────────────────────────
|
||||||
|
// SPAWN RAKUNA (Nočni spawn)
|
||||||
|
// ─────────────────────────────────────────────────────────────────────────
|
||||||
|
spawnRaccoon(x = null, y = null) {
|
||||||
|
if (x === null || y === null) {
|
||||||
|
const edge = Phaser.Math.Between(0, 3);
|
||||||
|
const margin = 100;
|
||||||
|
switch (edge) {
|
||||||
|
case 0: x = this.islandX + Phaser.Math.Between(margin, this.islandW - margin); y = this.islandY + margin; break;
|
||||||
|
case 1: x = this.islandX + this.islandW - margin; y = this.islandY + Phaser.Math.Between(margin, this.islandH - margin); break;
|
||||||
|
case 2: x = this.islandX + Phaser.Math.Between(margin, this.islandW - margin); y = this.islandY + this.islandH - margin; break;
|
||||||
|
case 3: x = this.islandX + margin; y = this.islandY + Phaser.Math.Between(margin, this.islandH - margin); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uporabimo placeholder zombi sprite, dokler ni rakuna (tint na sivo, pomanjšan)
|
||||||
|
let tex = this.scene.textures.exists('raccoon') ? 'raccoon' : 'zombie_shambler';
|
||||||
|
const sprite = this.scene.add.sprite(x, y, tex, 0)
|
||||||
|
.setScale(tex === 'raccoon' ? 1.0 : 0.3)
|
||||||
|
.setOrigin(0.5, 1.0)
|
||||||
|
.setDepth(y);
|
||||||
|
|
||||||
|
if (tex === 'zombie_shambler') sprite.setTint(0x777777); // Sivo-črna barva za rakuna
|
||||||
|
|
||||||
|
sprite.setAlpha(0);
|
||||||
|
this.scene.tweens.add({ targets: sprite, alpha: 1, duration: 800 });
|
||||||
|
|
||||||
|
const halo = this.scene.add.graphics().setDepth(y - 1);
|
||||||
|
halo.fillStyle(0xffaa00, 0.15); // Oranžen halo za rakune
|
||||||
|
halo.fillCircle(x, y - 10, 20);
|
||||||
|
|
||||||
|
const raccoon = {
|
||||||
|
sprite, halo, x, y, state: 'wandering', tamed: false,
|
||||||
|
hp: 10, maxHp: 10, dir: 'down',
|
||||||
|
wanderTimer: 0, wanderDirX: 0, wanderDirY: 1,
|
||||||
|
isRaccoon: true
|
||||||
|
};
|
||||||
|
|
||||||
|
this.zombies.push(raccoon);
|
||||||
|
console.log(`🦝 Rakun spawnan ponoči @ ${Math.round(x)},${Math.round(y)}`);
|
||||||
|
return raccoon;
|
||||||
|
}
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────────
|
||||||
// UPDATE — Kliči vsak frame iz scene.update()
|
// UPDATE — Kliči vsak frame iz scene.update()
|
||||||
// ─────────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────────
|
||||||
@@ -287,10 +335,10 @@ export default class ZombieSystem {
|
|||||||
moveX = Math.cos(angle) * speed * dt;
|
moveX = Math.cos(angle) * speed * dt;
|
||||||
moveY = Math.sin(angle) * speed * dt;
|
moveY = Math.sin(angle) * speed * dt;
|
||||||
|
|
||||||
// Rdeči halo (nevarnost)
|
// Rdeči halo (nevarnost) ali oranžen za rakune
|
||||||
z.halo.clear();
|
z.halo.clear();
|
||||||
z.halo.fillStyle(0xff0000, 0.18);
|
z.halo.fillStyle(z.isRaccoon ? 0xffaa00 : 0xff0000, 0.18);
|
||||||
z.halo.fillCircle(z.sprite.x, z.sprite.y - 20, 40);
|
z.halo.fillCircle(z.sprite.x, z.sprite.y - 20, z.isRaccoon ? 20 : 40);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// === TAVANJE ===
|
// === TAVANJE ===
|
||||||
|
|||||||
Reference in New Issue
Block a user