phase 11 koncano
This commit is contained in:
137
src/systems/WorldEventSystem.js
Normal file
137
src/systems/WorldEventSystem.js
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user