- Add src/utils/responsive.js with fontSize() helper - Mobile fonts scale 1.4x for better readability - Update all scenes to use responsive font sizes - Update deploy-k8s.sh with full deployment steps Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
212 lines
6.2 KiB
JavaScript
212 lines
6.2 KiB
JavaScript
import Phaser from 'phaser';
|
|
import { fontSize } from '../utils/responsive.js';
|
|
|
|
export default class MapScene extends Phaser.Scene {
|
|
constructor() {
|
|
super({ key: 'MapScene' });
|
|
}
|
|
|
|
init(data) {
|
|
// Receive inventory data from previous scene
|
|
this.inventory = data.inventory || { whaleOil: 0, fuel: 100, penguins: 0 };
|
|
}
|
|
|
|
create() {
|
|
// Ocean background
|
|
this.add.rectangle(400, 300, 800, 600, 0x1e5a8e);
|
|
|
|
// Title
|
|
this.add.text(400, 30, 'Navigation Map - Choose Your Destination', {
|
|
fontSize: fontSize(24),
|
|
fill: '#fff',
|
|
fontStyle: 'bold'
|
|
}).setOrigin(0.5);
|
|
|
|
// Draw some decorative waves
|
|
this.drawWaves();
|
|
|
|
// Current position marker (The Ship)
|
|
this.createLocation(400, 300, 'SHIP', 0x8B4513,
|
|
'Your current position. Click to return to ship deck.',
|
|
() => this.returnToShip());
|
|
|
|
// Hunting Grounds
|
|
this.createLocation(250, 200, 'HUNTING\nGROUNDS', 0x2d5f8e,
|
|
'Rich waters where whales gather. Dangerous but profitable!',
|
|
() => this.goToHunting());
|
|
|
|
// Antarctic Island
|
|
this.createLocation(600, 450, 'ANTARCTIC\nISLAND', 0xE0E0E0,
|
|
'Cold, desolate islands. Who knows what resources might be found...',
|
|
() => this.goToAntarctic());
|
|
|
|
// Port
|
|
this.createLocation(150, 500, 'PORT', 0x654321,
|
|
'Return to port to resupply fuel and sell whale oil.',
|
|
() => this.goToPort());
|
|
|
|
// Inventory display
|
|
this.createInventoryDisplay();
|
|
|
|
// Message box
|
|
this.createMessageBox();
|
|
this.showMessage('Select a destination. Watch your fuel levels!');
|
|
|
|
// Close map button
|
|
const closeButton = this.add.rectangle(750, 50, 80, 40, 0x8B0000);
|
|
closeButton.setInteractive({ useHandCursor: true });
|
|
closeButton.setStrokeStyle(2, 0xffffff);
|
|
|
|
const closeText = this.add.text(750, 50, 'CLOSE', {
|
|
fontSize: fontSize(16),
|
|
fill: '#fff'
|
|
}).setOrigin(0.5);
|
|
|
|
// Touch feedback (works on both touch and mouse)
|
|
closeButton.on('pointerdown', () => {
|
|
closeButton.setScale(0.95);
|
|
closeText.setScale(0.95);
|
|
});
|
|
|
|
closeButton.on('pointerup', () => {
|
|
closeButton.setScale(1.0);
|
|
closeText.setScale(1.0);
|
|
this.returnToShip();
|
|
});
|
|
}
|
|
|
|
drawWaves() {
|
|
// Decorative wave lines
|
|
const graphics = this.add.graphics();
|
|
graphics.lineStyle(2, 0x4a90c4, 0.5);
|
|
|
|
for (let i = 0; i < 10; i++) {
|
|
const y = 100 + i * 50;
|
|
graphics.beginPath();
|
|
for (let x = 0; x < 800; x += 20) {
|
|
const waveY = y + Math.sin((x + i * 30) * 0.02) * 10;
|
|
if (x === 0) {
|
|
graphics.moveTo(x, waveY);
|
|
} else {
|
|
graphics.lineTo(x, waveY);
|
|
}
|
|
}
|
|
graphics.strokePath();
|
|
}
|
|
}
|
|
|
|
createLocation(x, y, name, color, description, onClick) {
|
|
// Location marker
|
|
const marker = this.add.circle(x, y, 30, color);
|
|
marker.setInteractive({ useHandCursor: true });
|
|
marker.setStrokeStyle(3, 0xffffff);
|
|
|
|
// Location name
|
|
const text = this.add.text(x, y, name, {
|
|
fontSize: fontSize(12),
|
|
fill: '#fff',
|
|
fontStyle: 'bold',
|
|
align: 'center'
|
|
}).setOrigin(0.5);
|
|
|
|
// Hover effect (desktop)
|
|
marker.on('pointerover', () => {
|
|
marker.setScale(1.1);
|
|
this.showMessage(description);
|
|
});
|
|
|
|
marker.on('pointerout', () => {
|
|
marker.setScale(1);
|
|
});
|
|
|
|
// Touch feedback (works on both touch and mouse)
|
|
marker.on('pointerdown', () => {
|
|
marker.setScale(0.9);
|
|
text.setScale(0.9);
|
|
});
|
|
|
|
marker.on('pointerup', () => {
|
|
marker.setScale(1);
|
|
text.setScale(1);
|
|
onClick();
|
|
});
|
|
}
|
|
|
|
createInventoryDisplay() {
|
|
const panel = this.add.rectangle(80, 80, 140, 100, 0x000000, 0.8);
|
|
panel.setStrokeStyle(2, 0xffffff);
|
|
|
|
this.inventoryText = this.add.text(20, 40, '', {
|
|
fontSize: fontSize(14),
|
|
fill: '#fff'
|
|
});
|
|
|
|
this.updateInventoryDisplay();
|
|
}
|
|
|
|
updateInventoryDisplay() {
|
|
const lines = [
|
|
'Inventory:',
|
|
`Fuel: ${this.inventory.fuel}/100`,
|
|
`Oil: ${this.inventory.whaleOil}/50`
|
|
];
|
|
|
|
// Only show penguins if discovered (have at least one)
|
|
if (this.inventory.penguins > 0) {
|
|
lines.push(`Penguins: ${this.inventory.penguins}/20`);
|
|
}
|
|
|
|
this.inventoryText.setText(lines);
|
|
}
|
|
|
|
createMessageBox() {
|
|
this.messageBox = this.add.rectangle(400, 560, 760, 60, 0x000000, 0.8);
|
|
this.messageBox.setStrokeStyle(2, 0xcccccc);
|
|
|
|
this.messageText = this.add.text(400, 560, '', {
|
|
fontSize: fontSize(16),
|
|
fill: '#fff',
|
|
wordWrap: { width: 740 },
|
|
align: 'center'
|
|
}).setOrigin(0.5);
|
|
}
|
|
|
|
showMessage(message) {
|
|
this.messageText.setText(message);
|
|
}
|
|
|
|
returnToShip() {
|
|
this.scene.start('ShipDeckScene', { inventory: this.inventory });
|
|
}
|
|
|
|
goToHunting() {
|
|
// Sailing is free - fuel is only for cooking
|
|
this.scene.start('TransitionScene', {
|
|
inventory: this.inventory,
|
|
destination: 'hunting',
|
|
fuelCost: 0,
|
|
nextScene: 'HuntingScene'
|
|
});
|
|
}
|
|
|
|
goToAntarctic() {
|
|
// Sailing is free - fuel is only for cooking
|
|
this.scene.start('TransitionScene', {
|
|
inventory: this.inventory,
|
|
destination: 'antarctic',
|
|
fuelCost: 0,
|
|
nextScene: 'MapScene' // Will change to 'AntarcticScene' when implemented
|
|
});
|
|
}
|
|
|
|
goToPort() {
|
|
// Sailing is free
|
|
this.scene.start('TransitionScene', {
|
|
inventory: this.inventory,
|
|
destination: 'port',
|
|
fuelCost: 0,
|
|
nextScene: 'MapScene' // Will change to 'PortScene' when implemented
|
|
});
|
|
}
|
|
}
|