feat: add swimming whale to Deep Sea scene

- Whale enters from random edge, exits to different edge
- 5 second smooth swim with Sine.inOut easing
- 2 second respawn delay
- Bioluminescent eye glow effect
- Subtle bobbing animation during movement

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Thomas Richter
2026-02-05 00:46:30 +01:00
parent 3328269499
commit c220ea4b53

View File

@@ -10,6 +10,7 @@ export default class DeepSeaHuntingScene extends Phaser.Scene {
init(data) {
this.inventory = data.inventory || { whaleOil: 0, fuel: 100, penguins: 0 };
this.whalesHunted = 0;
this.currentWhale = null;
}
create() {
@@ -26,8 +27,11 @@ export default class DeepSeaHuntingScene extends Phaser.Scene {
// Fullscreen button
createFullscreenButton(this);
// Spawn first whale
this.spawnWhale();
// Show initial message
this.showMessage('Deep Sea Hunting - Coming Soon! Click RETURN to go back.');
this.showMessage('The leviathan approaches... Watch the depths!');
}
createDeepOceanAtmosphere() {
@@ -71,20 +75,120 @@ export default class DeepSeaHuntingScene extends Phaser.Scene {
ease: 'Sine.inOut'
});
}
}
// Giant shadow placeholder
const shadow = this.add.ellipse(400, 350, 250, 100, 0x000000, 0.4);
spawnWhale() {
// Get random entry and exit points on different edges
const edges = ['top', 'bottom', 'left', 'right'];
const entryEdge = edges[Math.floor(Math.random() * edges.length)];
// Pick a different edge for exit
const exitEdges = edges.filter(e => e !== entryEdge);
const exitEdge = exitEdges[Math.floor(Math.random() * exitEdges.length)];
const entry = this.getEdgePoint(entryEdge);
const exit = this.getEdgePoint(exitEdge);
// Calculate angle for whale rotation
const angle = Phaser.Math.Angle.Between(entry.x, entry.y, exit.x, exit.y);
// Create whale container
const whale = this.add.container(entry.x, entry.y);
// Whale body (large deep sea whale)
const body = this.add.ellipse(0, 0, 180, 70, 0x1a2a3a);
body.setStrokeStyle(2, 0x2a4a6a);
// Whale underbelly
const belly = this.add.ellipse(0, 10, 140, 40, 0x2a3a4a);
// Tail
const tail = this.add.triangle(-100, 0, 0, -35, 0, 35, -50, 0, 0x1a2a3a);
// Dorsal fin
const dorsalFin = this.add.triangle(20, -25, 0, 0, 30, 0, 15, -30, 0x1a2a3a);
// Eye (bioluminescent glow)
const eyeGlow = this.add.circle(60, -10, 12, 0x4a9fff, 0.3);
const eye = this.add.circle(60, -10, 6, 0x6abfff);
// Add glow effect to eye
this.tweens.add({
targets: shadow,
x: 450,
y: 370,
scaleX: 1.1,
scaleY: 0.9,
duration: 5000,
targets: eyeGlow,
alpha: { from: 0.3, to: 0.6 },
scale: { from: 1, to: 1.3 },
duration: 1000,
yoyo: true,
repeat: -1,
ease: 'Sine.inOut'
});
whale.add([tail, body, belly, dorsalFin, eyeGlow, eye]);
whale.setRotation(angle);
whale.setDepth(10);
this.currentWhale = whale;
// Subtle bobbing animation during movement
this.tweens.add({
targets: whale,
scaleY: { from: 1, to: 1.05 },
duration: 800,
yoyo: true,
repeat: -1,
ease: 'Sine.inOut'
});
// Move whale from entry to exit over 5 seconds
this.tweens.add({
targets: whale,
x: exit.x,
y: exit.y,
duration: 5000,
ease: 'Sine.inOut',
onComplete: () => {
this.onWhaleExit(whale);
}
});
}
getEdgePoint(edge) {
const margin = 100; // How far off-screen to spawn
const padding = 100; // Padding from corners
switch (edge) {
case 'top':
return {
x: padding + Math.random() * (800 - padding * 2),
y: -margin
};
case 'bottom':
return {
x: padding + Math.random() * (800 - padding * 2),
y: 600 + margin
};
case 'left':
return {
x: -margin,
y: padding + Math.random() * (600 - padding * 2)
};
case 'right':
return {
x: 800 + margin,
y: padding + Math.random() * (600 - padding * 2)
};
}
}
onWhaleExit(whale) {
// Destroy the whale
whale.destroy();
this.currentWhale = null;
// Respawn after 2 seconds
this.time.delayedCall(2000, () => {
this.spawnWhale();
});
}
createHUD() {