Fix crashes, remove Gronk, add Water/Wind anims, fix Tiled paths, clean plants assets
This commit is contained in:
@@ -6,6 +6,13 @@ class ErrorHandler {
|
||||
return false;
|
||||
};
|
||||
window.addEventListener('unhandledrejection', (event) => {
|
||||
// IGNORE AUDIO DECODING ERRORS (Phaser/Electron issue)
|
||||
const msg = event.reason ? String(event.reason) : '';
|
||||
if (msg.includes('Unable to decode audio data') || msg.includes('EncodingError') || msg.includes(':0:0')) {
|
||||
console.warn('🔇 Ignored Critical Audio Error (Game continues):', msg);
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
ErrorHandler.showError('Unhandled Promise Rejection', '', 0, 0, event.reason);
|
||||
});
|
||||
console.log('🛡️ Global Error Handler Initialized');
|
||||
|
||||
@@ -227,9 +227,64 @@ class GameScene extends Phaser.Scene {
|
||||
map.layers.forEach(layer => {
|
||||
if (layer.type === 'tilelayer') {
|
||||
const createdLayer = map.createLayer(layer.name, tileset, 0, 0);
|
||||
|
||||
// Set Depth based on layer name or order
|
||||
if (layer.name === 'Objects') createdLayer.setDepth(10); // Above ground
|
||||
if (layer.name === 'Collision') createdLayer.setVisible(false); // Hide collision usually
|
||||
if (layer.name === 'Objects') createdLayer.setDepth(10);
|
||||
|
||||
if (layer.name === 'Collision') {
|
||||
createdLayer.setVisible(false);
|
||||
this.collisionLayer = createdLayer;
|
||||
this.collisionLayer.setCollisionByExclusion([-1]);
|
||||
console.log('🚧 Collision Layer Set!');
|
||||
}
|
||||
|
||||
// 💧 DYNAMIC TILED EFFECTS (Shine)
|
||||
// Check for custom properties from Tiled
|
||||
const layerProps = layer.properties || [];
|
||||
const getProp = (n) => {
|
||||
if (Array.isArray(layerProps)) {
|
||||
const p = layerProps.find(x => x.name === n);
|
||||
return p ? p.value : undefined;
|
||||
}
|
||||
return layerProps[n];
|
||||
};
|
||||
|
||||
const shineIntensity = getProp('shine_intensity');
|
||||
const isWind = getProp('isWind');
|
||||
|
||||
// Apply Shine if prop exists OR if name is Water/Voda
|
||||
if (shineIntensity !== undefined || layer.name === 'Water' || layer.name === 'Voda') {
|
||||
const intensity = shineIntensity !== undefined ? parseFloat(shineIntensity) : 5;
|
||||
|
||||
// Validate intensity
|
||||
if (!isNaN(intensity) && intensity > 0 && createdLayer.postFX) {
|
||||
console.log(`💧 Applying Shine to layer '${layer.name}' (Intensity: ${intensity})`);
|
||||
const shine = createdLayer.postFX.addShine(1, 0.2, intensity);
|
||||
|
||||
// Animate shine speed for 'glimmer' effect
|
||||
this.tweens.add({
|
||||
targets: shine,
|
||||
speed: 0.5,
|
||||
duration: 2000,
|
||||
yoyo: true,
|
||||
repeat: -1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 🌬️ WIND (Wobble Effect)
|
||||
if (isWind) {
|
||||
console.log(`🌬️ Applying Wind to '${layer.name}'`);
|
||||
this.tweens.add({
|
||||
targets: createdLayer,
|
||||
x: createdLayer.x + 3,
|
||||
skewX: 0.015,
|
||||
duration: 2000 + Math.random() * 500,
|
||||
ease: 'Sine.easeInOut',
|
||||
yoyo: true,
|
||||
repeat: -1
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -238,6 +293,20 @@ class GameScene extends Phaser.Scene {
|
||||
try {
|
||||
// 🎵 MUSIC PROP
|
||||
const mapMusic = map.properties && map.properties.find(p => p.name === 'music')?.value;
|
||||
|
||||
// 🌲 FOREST AMBIENT (Safe Play)
|
||||
try {
|
||||
// Verify cache existence first to avoid decode errors propagating
|
||||
if (this.cache.audio.exists('forest_ambient')) {
|
||||
this.sound.play('forest_ambient', { loop: true, volume: 0.3 });
|
||||
console.log('🌲 Playing Forest Ambient');
|
||||
} else {
|
||||
console.warn('⚠️ Forest Ambient skipped (Not in cache/Load failed)');
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('❌ Audio play CRASH prevented:', e);
|
||||
}
|
||||
|
||||
if (mapMusic) {
|
||||
console.log(`🎵 Map Triggered Music: ${mapMusic}`);
|
||||
// Use sound manager or direct play (SoundManager preferred but let's check safety)
|
||||
@@ -266,6 +335,15 @@ class GameScene extends Phaser.Scene {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 🎭 ACTORS LAYER (NPCs including Gronk)
|
||||
const actorsLayer = map.getObjectLayer('Actors') || map.getObjectLayer('Objects');
|
||||
if (actorsLayer && actorsLayer.objects) {
|
||||
console.log(`🎭 Found ${actorsLayer.objects.length} Actors`);
|
||||
actorsLayer.objects.forEach(obj => {
|
||||
// Gronk disabled per user request
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('⚠️ Error parsing object layers:', err);
|
||||
}
|
||||
@@ -429,11 +507,11 @@ class GameScene extends Phaser.Scene {
|
||||
// Odstrani // če želiš sadovnjak
|
||||
/*
|
||||
console.log('🍎 Ustvarjam sadovnjak...');
|
||||
|
||||
|
||||
const orchardX = 35; // Lokacija sadovnjaka
|
||||
const orchardY = 60;
|
||||
const orchardSize = 10; // 10x10 območje
|
||||
|
||||
|
||||
// 1. Očisti območje (odstrani obstoječe drevese)
|
||||
for (let x = orchardX; x < orchardX + orchardSize; x++) {
|
||||
for (let y = orchardY; y < orchardY + orchardSize; y++) {
|
||||
@@ -442,7 +520,7 @@ class GameScene extends Phaser.Scene {
|
||||
if (this.terrainSystem.decorationsMap.has(key)) {
|
||||
this.terrainSystem.removeDecoration(x, y);
|
||||
}
|
||||
|
||||
|
||||
// Spremeni teren v travo
|
||||
if (this.terrainSystem.tiles[y] && this.terrainSystem.tiles[y][x]) {
|
||||
this.terrainSystem.tiles[y][x].type = 'grass';
|
||||
@@ -454,12 +532,12 @@ class GameScene extends Phaser.Scene {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 2. Dodaj SADIKE (tree_sapling) - bodo rasle v sadna drevesa!
|
||||
const fruitTreeTypes = ['tree_apple', 'tree_orange', 'tree_cherry'];
|
||||
let treeCount = 0;
|
||||
const saplingPositions = []; // Shrani pozicije za ograje
|
||||
|
||||
|
||||
for (let x = orchardX + 1; x < orchardX + orchardSize - 1; x += 2) {
|
||||
for (let y = orchardY + 1; y < orchardY + orchardSize - 1; y += 2) {
|
||||
if (x >= 0 && x < 100 && y >= 0 && y < 100) {
|
||||
@@ -470,7 +548,7 @@ class GameScene extends Phaser.Scene {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 3. Dodaj LESENO OGRAJO okoli vsakega drevesa (3x3 kvadrat)
|
||||
saplingPositions.forEach(pos => {
|
||||
// Ograja okoli drevesa (3x3)
|
||||
@@ -488,14 +566,14 @@ class GameScene extends Phaser.Scene {
|
||||
// Desna stran
|
||||
{ x: pos.x + 1, y: pos.y }
|
||||
];
|
||||
|
||||
|
||||
fencePositions.forEach(fPos => {
|
||||
if (fPos.x >= 0 && fPos.x < 100 && fPos.y >= 0 && fPos.y < 100) {
|
||||
this.buildSystem.placeSingleFence(fPos.x, fPos.y, 'fence_horizontal', false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// 4. Dodaj ZUNANJO OGRAJO okoli celega sadovnjaka
|
||||
this.buildSystem.placeFenceRectangle(
|
||||
orchardX - 1,
|
||||
@@ -505,7 +583,7 @@ class GameScene extends Phaser.Scene {
|
||||
'fence_post',
|
||||
false
|
||||
);
|
||||
|
||||
|
||||
// 5. Dodaj cvetje med ograjami
|
||||
for (let x = orchardX; x < orchardX + orchardSize; x++) {
|
||||
for (let y = orchardY; y < orchardY + orchardSize; y++) {
|
||||
@@ -517,21 +595,21 @@ class GameScene extends Phaser.Scene {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 6. RAST DREVES - Sadike bodo rasle v sadna drevesa!
|
||||
// Nastavi timer za rast (vsako drevo raste po 30 sekundah)
|
||||
saplingPositions.forEach((pos, index) => {
|
||||
this.time.delayedCall(30000 + (index * 2000), () => {
|
||||
const key = `${pos.x},${pos.y}`;
|
||||
|
||||
|
||||
// Odstrani sadiko
|
||||
if (this.terrainSystem.decorationsMap.has(key)) {
|
||||
this.terrainSystem.removeDecoration(pos.x, pos.y);
|
||||
}
|
||||
|
||||
|
||||
// Dodaj SADNO DREVO
|
||||
this.terrainSystem.addDecoration(pos.x, pos.y, pos.type);
|
||||
|
||||
|
||||
// Animacija rasti
|
||||
if (this.terrainSystem.visibleDecorations.has(key)) {
|
||||
const sprite = this.terrainSystem.visibleDecorations.get(key);
|
||||
@@ -544,11 +622,11 @@ class GameScene extends Phaser.Scene {
|
||||
ease: 'Bounce.out'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
console.log(`🌳 Drevo zraslo: ${pos.type} na (${pos.x}, ${pos.y})`);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
console.log(`✅ Sadovnjak ustvarjen na (${orchardX}, ${orchardY}) - ${treeCount} sadik (bodo rasle v 30s)`);
|
||||
*/
|
||||
// ========================================================
|
||||
@@ -706,6 +784,9 @@ class GameScene extends Phaser.Scene {
|
||||
// ALL NPCs REMOVED - Solo farming mode
|
||||
console.log('🌾 Solo farming mode - no NPCs');
|
||||
|
||||
// Gronk logic removed from create() fallback
|
||||
|
||||
|
||||
// FPS Monitor (Performance)
|
||||
// FPS Monitor - DISABLED (Using UnifiedStatsPanel instead)
|
||||
// console.log('📊 Initializing FPS Monitor...');
|
||||
@@ -801,7 +882,7 @@ class GameScene extends Phaser.Scene {
|
||||
console.log('💡 Initializing Lighting & Shadow System... (DISABLED FOR DEBUG)');
|
||||
/*
|
||||
this.lightingSystem = new LightingSystem(this);
|
||||
|
||||
|
||||
// Create player shadow
|
||||
if (this.player) {
|
||||
this.lightingSystem.createShadow(this.player, 12, 30, 15);
|
||||
@@ -2453,17 +2534,17 @@ class GameScene extends Phaser.Scene {
|
||||
|
||||
/*
|
||||
if (!this.player || this.npcs.length > 50) return;
|
||||
|
||||
|
||||
const playerPos = this.player.getPosition();
|
||||
const angle = Math.random() * Math.PI * 2;
|
||||
const distance = Phaser.Math.Between(15, 25);
|
||||
|
||||
|
||||
const spawnX = Math.floor(playerPos.x + Math.cos(angle) * distance);
|
||||
const spawnY = Math.floor(playerPos.y + Math.sin(angle) * distance);
|
||||
|
||||
|
||||
if (spawnX < 0 || spawnX >= 100 || spawnY < 0 || spawnY >= 100) return;
|
||||
if (Phaser.Math.Distance.Between(spawnX, spawnY, 20, 20) < 15) return;
|
||||
|
||||
|
||||
const tile = this.terrainSystem.getTile(spawnX, spawnY);
|
||||
if (tile && tile.type !== 'water') {
|
||||
console.log(`🌑 Night Spawn: Zombie at ${spawnX},${spawnY}`);
|
||||
@@ -2720,11 +2801,47 @@ class GameScene extends Phaser.Scene {
|
||||
if (bird.x < -100) {
|
||||
bird.x = width + 100;
|
||||
bird.y = 100 + Math.random() * 200;
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setupGronk() { }
|
||||
|
||||
// 🧛♂️ GRONK SPAWN METHOD (Advanced Wander AI)
|
||||
if(this.gronk.aiState === 'IDLE') {
|
||||
const rand = Math.random();
|
||||
if (rand < 0.3) { // 30% Vape
|
||||
this.gronk.aiState = 'VAPE';
|
||||
this.gronk.anims.play('gronk_vape');
|
||||
emitVape();
|
||||
this.gronk.nextDecisionTime = time + 3000;
|
||||
setTimeout(() => { if (this.gronk && this.gronk.active) this.gronk.aiState = 'IDLE'; }, 2500);
|
||||
} else { // 70% Wander
|
||||
const angle = Math.random() * Math.PI * 2;
|
||||
const dist = 30 + Math.random() * wanderRadius; // Min 30px move
|
||||
const tx = this.gronk.homePos.x + Math.cos(angle) * dist;
|
||||
const ty = this.gronk.homePos.y + Math.sin(angle) * dist;
|
||||
|
||||
this.gronk.moveTarget = new Phaser.Math.Vector2(tx, ty);
|
||||
this.physics.moveToObject(this.gronk, this.gronk.moveTarget, moveSpeed);
|
||||
this.gronk.aiState = 'MOVE';
|
||||
this.gronk.nextDecisionTime = time + 5000; // Timeout
|
||||
}
|
||||
} else if (this.gronk.aiState === 'MOVE') {
|
||||
const dist = Phaser.Math.Distance.Between(this.gronk.x, this.gronk.y, this.gronk.moveTarget.x, this.gronk.moveTarget.y);
|
||||
if (dist < 10) {
|
||||
this.gronk.body.reset(this.gronk.x, this.gronk.y);
|
||||
this.gronk.aiState = 'IDLE';
|
||||
this.gronk.nextDecisionTime = time + 1000 + Math.random() * 2000;
|
||||
} else if (time >= this.gronk.nextDecisionTime) { // Stuck/Timeout
|
||||
this.gronk.body.reset(this.gronk.x, this.gronk.y);
|
||||
this.gronk.aiState = 'IDLE';
|
||||
this.gronk.nextDecisionTime = time + 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ class PreloadScene extends Phaser.Scene {
|
||||
// Trees
|
||||
this.load.image('tileset_Tree_Apple', 'assets/references/trees/apple/apple_tree.png');
|
||||
this.load.image('tileset_Tree_Cherry', 'assets/references/trees/cherry/cherry_tree.png');
|
||||
this.load.image('tileset_Tree_Dead', 'assets/references/trees/dead/dead_tree.png');
|
||||
this.load.image('tileset_Tree_Dead', 'assets/maps/tilesets/Tree_Dead.png');
|
||||
|
||||
// Buildings
|
||||
this.load.image('tileset_House_Gothic', 'assets/references/buildings/kai_house/04_gothic_house.png');
|
||||
@@ -143,6 +143,16 @@ class PreloadScene extends Phaser.Scene {
|
||||
this.loadAudioSafe('kai_voice_4', basePath + 'kai/kai_04.mp3');
|
||||
this.loadAudioSafe('kai_voice_5', basePath + 'kai/kai_05.mp3');
|
||||
|
||||
// 🎵 AMBIENT
|
||||
this.loadAudioSafe('forest_ambient', 'assets/audio/music/forest_ambient.mp3');
|
||||
|
||||
// 🧛♂️ GRONK FULL SPRITESHEET (Custom Animation Set)
|
||||
// 🧛♂️ GRONK PRO SPRITESHEET (Custom Animation Set - Cleaned & Centered)
|
||||
this.load.spritesheet('gronk_pro_sheet', 'assets/characters/gronk_pro_sheet.png', {
|
||||
frameWidth: 128,
|
||||
frameHeight: 128
|
||||
});
|
||||
|
||||
// Ana voices
|
||||
this.loadAudioSafe('ana_voice_1', basePath + 'ana/ana_01.mp3');
|
||||
this.loadAudioSafe('ana_voice_2', basePath + 'ana/ana_02.mp3');
|
||||
@@ -240,6 +250,42 @@ class PreloadScene extends Phaser.Scene {
|
||||
frameRate: 1
|
||||
});
|
||||
|
||||
// 🧛♂️ GRONK ANIMATIONS
|
||||
// Down
|
||||
this.anims.create({
|
||||
key: 'gronk_walk_down',
|
||||
frames: this.anims.generateFrameNumbers('gronk_pro_sheet', { start: 0, end: 3 }),
|
||||
frameRate: 8,
|
||||
repeat: -1
|
||||
});
|
||||
// Right
|
||||
this.anims.create({
|
||||
key: 'gronk_walk_right',
|
||||
frames: this.anims.generateFrameNumbers('gronk_pro_sheet', { start: 4, end: 7 }),
|
||||
frameRate: 8,
|
||||
repeat: -1
|
||||
});
|
||||
// Up
|
||||
this.anims.create({
|
||||
key: 'gronk_walk_up',
|
||||
frames: this.anims.generateFrameNumbers('gronk_pro_sheet', { start: 8, end: 11 }),
|
||||
frameRate: 8,
|
||||
repeat: -1
|
||||
});
|
||||
// Vape (Special)
|
||||
this.anims.create({
|
||||
key: 'gronk_vape',
|
||||
frames: this.anims.generateFrameNumbers('gronk_pro_sheet', { start: 12, end: 15 }),
|
||||
frameRate: 8,
|
||||
repeat: 0 // Play once
|
||||
});
|
||||
// Idle
|
||||
this.anims.create({
|
||||
key: 'gronk_idle', // Default idle (Down)
|
||||
frameRate: 2,
|
||||
repeat: -1
|
||||
});
|
||||
|
||||
console.log('🎞️ Animations created!');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user