diff --git a/src/main.js b/src/main.js index bbd2f76..d9ecd07 100644 --- a/src/main.js +++ b/src/main.js @@ -4,6 +4,7 @@ import ShipDeckScene from './scenes/ShipDeckScene.js'; import MapScene from './scenes/MapScene.js'; import TransitionScene from './scenes/TransitionScene.js'; import HuntingScene from './scenes/HuntingScene.js'; +import DeepSeaHuntingScene from './scenes/DeepSeaHuntingScene.js'; const config = { type: Phaser.AUTO, @@ -11,7 +12,7 @@ const config = { height: 600, parent: 'game-container', backgroundColor: '#2d5f8e', - scene: [IntroScene, ShipDeckScene, MapScene, TransitionScene, HuntingScene], + scene: [IntroScene, ShipDeckScene, MapScene, TransitionScene, HuntingScene, DeepSeaHuntingScene], physics: { default: 'arcade', arcade: { diff --git a/src/scenes/DeepSeaHuntingScene.js b/src/scenes/DeepSeaHuntingScene.js new file mode 100644 index 0000000..1cc88be --- /dev/null +++ b/src/scenes/DeepSeaHuntingScene.js @@ -0,0 +1,142 @@ +import Phaser from 'phaser'; +import { fontSize } from '../utils/responsive.js'; +import { createFullscreenButton } from '../utils/fullscreen.js'; + +export default class DeepSeaHuntingScene extends Phaser.Scene { + constructor() { + super({ key: 'DeepSeaHuntingScene' }); + } + + init(data) { + this.inventory = data.inventory || { whaleOil: 0, fuel: 100, penguins: 0 }; + this.whalesHunted = 0; + } + + create() { + // Dark deep ocean background + this.add.rectangle(400, 300, 800, 600, 0x0a1a2a); + + // Create atmospheric effects + this.createDeepOceanAtmosphere(); + + // UI elements + this.createHUD(); + this.createInstructions(); + + // Fullscreen button + createFullscreenButton(this); + + // Show initial message + this.showMessage('Deep Sea Hunting - Coming Soon! Click RETURN to go back.'); + } + + createDeepOceanAtmosphere() { + // Gradient darkness + for (let i = 0; i < 6; i++) { + const alpha = 0.05 + i * 0.03; + this.add.rectangle(400, 500 - i * 80, 800, 100, 0x000000, alpha); + } + + // Subtle waves + const graphics = this.add.graphics(); + graphics.lineStyle(2, 0x1a3a5a, 0.3); + + for (let i = 0; i < 8; i++) { + const y = 80 + i * 70; + graphics.beginPath(); + for (let x = 0; x < 800; x += 30) { + const waveY = y + Math.sin((x + i * 50) * 0.012) * 8; + if (x === 0) { + graphics.moveTo(x, waveY); + } else { + graphics.lineTo(x, waveY); + } + } + graphics.strokePath(); + } + + // Bioluminescent particles + for (let i = 0; i < 20; i++) { + const x = Math.random() * 800; + const y = 100 + Math.random() * 400; + const particle = this.add.circle(x, y, 2 + Math.random() * 2, 0x4a9fff, 0.5); + + this.tweens.add({ + targets: particle, + alpha: { from: 0.5, to: 0.1 }, + y: y - 30, + duration: 3000 + Math.random() * 2000, + yoyo: true, + repeat: -1, + ease: 'Sine.inOut' + }); + } + + // Giant shadow placeholder + const shadow = this.add.ellipse(400, 350, 250, 100, 0x000000, 0.4); + this.tweens.add({ + targets: shadow, + x: 450, + y: 370, + scaleX: 1.1, + scaleY: 0.9, + duration: 5000, + yoyo: true, + repeat: -1, + ease: 'Sine.inOut' + }); + } + + createHUD() { + // HUD background + const hudBg = this.add.rectangle(400, 30, 780, 50, 0x000000, 0.7); + hudBg.setStrokeStyle(2, 0x4a9fff); + + // Stats + this.statsText = this.add.text(20, 15, '', { + fontSize: fontSize(16), + fill: '#4a9fff' + }); + + // Return button + const returnBtn = this.add.rectangle(750, 30, 80, 35, 0x1a3a5a); + returnBtn.setInteractive({ useHandCursor: true }); + returnBtn.setStrokeStyle(2, 0x4a9fff); + + const returnText = this.add.text(750, 30, 'RETURN', { + fontSize: fontSize(14), + fill: '#4a9fff' + }).setOrigin(0.5); + + returnBtn.on('pointerdown', () => { + this.returnToMap(); + }); + + this.updateStats(); + } + + updateStats() { + this.statsText.setText([ + `Fuel: ${this.inventory.fuel}/100`, + `Oil: ${this.inventory.whaleOil}/50`, + `Leviathans: ${this.whalesHunted}` + ]); + } + + createInstructions() { + this.messageText = this.add.text(400, 570, '', { + fontSize: fontSize(16), + fill: '#4a9fff', + backgroundColor: '#000000', + padding: { x: 10, y: 5 } + }).setOrigin(0.5); + } + + showMessage(text) { + this.messageText.setText(text); + } + + returnToMap() { + this.scene.start('MapScene', { inventory: this.inventory }); + } +} diff --git a/src/scenes/MapScene.js b/src/scenes/MapScene.js index 4e06b3c..70efa85 100644 --- a/src/scenes/MapScene.js +++ b/src/scenes/MapScene.js @@ -46,6 +46,11 @@ export default class MapScene extends Phaser.Scene { 'Return to port to resupply fuel and sell whale oil.', () => this.goToPort()); + // Deep Sea - Alternative hunting area + this.createLocation(550, 150, 'DEEP\nSEA', 0x0a2a4a, + 'Treacherous deep waters. Giant whales lurk in the abyss...', + () => this.goToDeepSea()); + // Inventory display this.createInventoryDisplay(); @@ -212,4 +217,14 @@ export default class MapScene extends Phaser.Scene { nextScene: 'MapScene' // Will change to 'PortScene' when implemented }); } + + goToDeepSea() { + // Sailing is free - fuel is only for cooking + this.scene.start('TransitionScene', { + inventory: this.inventory, + destination: 'deepsea', + fuelCost: 0, + nextScene: 'DeepSeaHuntingScene' + }); + } } diff --git a/src/scenes/TransitionScene.js b/src/scenes/TransitionScene.js index 0a3aacb..85c7f74 100644 --- a/src/scenes/TransitionScene.js +++ b/src/scenes/TransitionScene.js @@ -125,6 +125,12 @@ export default class TransitionScene extends Phaser.Scene { description: 'The familiar harbor comes into view. Seagulls circle overhead.\nYou can already smell the taverns and hear the merchants haggling.\nTime to resupply and sell your cargo.', backgroundColor: 0x654321, visualType: 'harbor' + }, + 'deepsea': { + title: 'Descending into the Deep Sea', + description: 'The waters grow dark and cold. Your ship ventures into uncharted depths.\nMassive shadows move beneath the surface. The crew whispers of leviathans.\nOnly the bravest—or most foolish—hunt here...', + backgroundColor: 0x0a1a2a, + visualType: 'deep_ocean' } }; @@ -147,6 +153,9 @@ export default class TransitionScene extends Phaser.Scene { case 'harbor': this.createHarbor(); break; + case 'deep_ocean': + this.createDeepOcean(); + break; default: this.createOcean(); break; @@ -305,4 +314,74 @@ export default class TransitionScene extends Phaser.Scene { graphics.strokePath(); } } + + createDeepOcean() { + // Dark, eerie deep ocean atmosphere + + // Gradient effect with darker rectangles + for (let i = 0; i < 6; i++) { + const alpha = 0.1 + i * 0.05; + this.add.rectangle(400, 50 + i * 50, 800, 50, 0x000000, alpha); + } + + // Subtle dark waves + const graphics = this.add.graphics(); + graphics.lineStyle(2, 0x1a3a5a, 0.4); + + for (let i = 0; i < 6; i++) { + const y = 80 + i * 50; + graphics.beginPath(); + for (let x = 0; x < 800; x += 25) { + const waveY = y + Math.sin((x + i * 40) * 0.015) * 12; + if (x === 0) { + graphics.moveTo(x, waveY); + } else { + graphics.lineTo(x, waveY); + } + } + graphics.strokePath(); + } + + // Massive shadows lurking below + for (let i = 0; i < 2; i++) { + const x = 200 + i * 400; + const y = 200 + Math.random() * 80; + + // Giant whale shadow + const shadow = this.add.ellipse(x, y, 200, 80, 0x000000, 0.3); + + // Slow, ominous movement + this.tweens.add({ + targets: shadow, + x: x + 30, + y: y + 15, + scaleX: 1.1, + duration: 4000, + yoyo: true, + repeat: -1, + ease: 'Sine.inOut' + }); + } + + // Bioluminescent particles + for (let i = 0; i < 15; i++) { + const x = Math.random() * 800; + const y = Math.random() * 300; + const particle = this.add.circle(x, y, 2, 0x4a9fff, 0.6); + + this.tweens.add({ + targets: particle, + alpha: { from: 0.6, to: 0.1 }, + y: y - 20, + duration: 2000 + Math.random() * 2000, + yoyo: true, + repeat: -1, + ease: 'Sine.inOut' + }); + } + + // Ship silhouette at top + this.add.rectangle(100, 60, 70, 35, 0x1a1a1a, 0.8); + this.add.polygon(100, 45, [0, 0, -35, 30, 35, 30], 0x2a2a2a, 0.8); + } }