phase 11 koncano

This commit is contained in:
2025-12-08 14:01:41 +01:00
parent 07f0752d81
commit f3d476e843
21 changed files with 1503 additions and 200 deletions

View File

@@ -0,0 +1,137 @@
class WorldEventSystem {
constructor(scene) {
this.scene = scene;
this.activeEvents = [];
this.bats = [];
this.owl = null;
}
/*
* BATS: Visual effect for evening/night
*/
spawnBatSwarm() {
console.log('🦇 Bat Swarm Incoming!');
const count = 10 + Math.floor(Math.random() * 10);
for (let i = 0; i < count; i++) {
// Start right-side of screen, random height
const sx = this.scene.scale.width + 50 + Math.random() * 200;
const sy = Math.random() * (this.scene.scale.height / 2); // Top half
const bat = this.scene.add.sprite(sx, sy, 'bat');
bat.setDepth(2000); // Above most things
bat.setScrollFactor(0); // Screen space (UI layer) or World space?
// Better world space if we want them to feel like part of the world, but screen space is easier for "effect".
// Let's stick to Screen Space for "Ambience".
// Random speed
const speed = 150 + Math.random() * 100;
this.bats.push({ sprite: bat, speed: speed });
}
}
/*
* NIGHT OWL: Delivers a gift
*/
spawnNightOwl() {
if (this.owl) return; // Only one at a time
console.log('🦉 Night Owl Arriving!');
// Spawn top-left
const sx = -50;
const sy = 100;
const owl = this.scene.add.sprite(sx, sy, 'owl');
owl.setDepth(2000);
owl.setScrollFactor(0); // Screen space for delivery
this.owl = {
sprite: owl,
state: 'ARRIVING', // ARRIVING, DELIVERING, LEAVING
timer: 0,
targetX: this.scene.scale.width / 2,
targetY: this.scene.scale.height / 3
};
if (this.scene.soundManager) {
// Play owl hoot sound (placeholder or generic)
// this.scene.soundManager.playHoot();
}
this.scene.events.emit('show-floating-text', {
x: this.scene.player.sprite.x,
y: this.scene.player.sprite.y - 120,
text: '🦉 Hoot Hoot!',
color: '#FFA500'
});
}
update(delta) {
// 1. Bats
for (let i = this.bats.length - 1; i >= 0; i--) {
const b = this.bats[i];
b.sprite.x -= b.speed * (delta / 1000); // Fly left
b.sprite.y += (Math.sin(b.sprite.x * 0.02) * 2); // Wobbly flight
if (b.sprite.x < -50) {
b.sprite.destroy();
this.bats.splice(i, 1);
}
}
// 2. Owl
if (this.owl) {
const o = this.owl;
const speed = 200 * (delta / 1000);
if (o.state === 'ARRIVING') {
const dx = o.targetX - o.sprite.x;
const dy = o.targetY - o.sprite.y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 10) {
o.state = 'DELIVERING';
o.timer = 0;
this.dropGift();
} else {
o.sprite.x += (dx / dist) * speed;
o.sprite.y += (dy / dist) * speed;
}
} else if (o.state === 'DELIVERING') {
o.timer += delta;
if (o.timer > 1000) { // Hover for 1s
o.state = 'LEAVING';
}
} else if (o.state === 'LEAVING') {
o.sprite.x += speed; // Fly right
o.sprite.y -= speed * 0.5; // Fly up
if (o.sprite.x > this.scene.scale.width + 50) {
o.sprite.destroy();
this.owl = null;
}
}
}
}
dropGift() {
console.log('🎁 Owl dropped a gift!');
const p = this.scene.player;
// Spawn loot at player pos (World Space)
if (this.scene.interactionSystem) {
// Random gift: Gold or maybe a rare item
const r = Math.random();
let item = 'flower_red';
let count = 1;
if (r < 0.3) { item = 'coin_gold'; count = 10; }
else if (r < 0.6) { item = 'seeds_corn'; count = 5; }
else if (r < 0.9) { item = 'item_scrap'; count = 3; }
else { item = 'artefact_old'; count = 1; } // Rare!
this.scene.interactionSystem.spawnLoot(p.gridX, p.gridY, item, count);
}
}
}