Files
whalehunting/src/scenes/MapScene.js
Thomas Richter 1154a78908 feat: add responsive font sizing for mobile
- 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>
2026-02-04 23:50:29 +01:00

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
});
}
}