Initial commit: Whale hunting adventure game
- Set up Phaser 3 game framework with Vite - Created ship deck scene with interactive objects - Implemented navigation map with destination selection - Added transition screens for travel between locations - Inventory system for tracking fuel, whale oil, and penguins - Three destination types: hunting grounds, Antarctic islands, and port 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
165
src/scenes/ShipDeckScene.js
Normal file
165
src/scenes/ShipDeckScene.js
Normal file
@@ -0,0 +1,165 @@
|
||||
import Phaser from 'phaser';
|
||||
|
||||
export default class ShipDeckScene extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'ShipDeckScene' });
|
||||
this.inventory = {
|
||||
whaleOil: 0,
|
||||
fuel: 100,
|
||||
penguins: 0
|
||||
};
|
||||
}
|
||||
|
||||
init(data) {
|
||||
// Receive inventory data when returning from other scenes
|
||||
if (data && data.inventory) {
|
||||
this.inventory = data.inventory;
|
||||
}
|
||||
}
|
||||
|
||||
create() {
|
||||
// Background - ship deck
|
||||
this.add.rectangle(400, 300, 800, 600, 0x8B4513);
|
||||
this.add.text(400, 30, 'Ship Deck - The Whaling Vessel', {
|
||||
fontSize: '24px',
|
||||
fill: '#fff'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
// Create interactive areas
|
||||
this.createDeck();
|
||||
this.createBarrels();
|
||||
this.createWheel();
|
||||
this.createInventoryDisplay();
|
||||
this.createMessageBox();
|
||||
|
||||
// Instructions
|
||||
this.add.text(400, 560, 'Click on objects to interact', {
|
||||
fontSize: '16px',
|
||||
fill: '#ffff99'
|
||||
}).setOrigin(0.5);
|
||||
}
|
||||
|
||||
createDeck() {
|
||||
// Ship deck planks
|
||||
for (let i = 0; i < 8; i++) {
|
||||
this.add.rectangle(400, 200 + i * 30, 700, 25, 0x654321)
|
||||
.setStrokeStyle(2, 0x3d2817);
|
||||
}
|
||||
}
|
||||
|
||||
createBarrels() {
|
||||
// Fuel barrel
|
||||
const fuelBarrel = this.add.rectangle(150, 350, 60, 80, 0x8B0000);
|
||||
fuelBarrel.setInteractive({ useHandCursor: true });
|
||||
fuelBarrel.setStrokeStyle(3, 0x000000);
|
||||
|
||||
this.add.text(150, 350, 'FUEL', {
|
||||
fontSize: '12px',
|
||||
fill: '#fff'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
fuelBarrel.on('pointerdown', () => {
|
||||
this.showMessage(`Fuel barrel: ${this.inventory.fuel} units remaining. This keeps the ship running.`);
|
||||
});
|
||||
|
||||
// Whale oil barrel
|
||||
const oilBarrel = this.add.rectangle(250, 350, 60, 80, 0x4B4B00);
|
||||
oilBarrel.setInteractive({ useHandCursor: true });
|
||||
oilBarrel.setStrokeStyle(3, 0x000000);
|
||||
|
||||
this.add.text(250, 350, 'OIL', {
|
||||
fontSize: '12px',
|
||||
fill: '#fff'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
oilBarrel.on('pointerdown', () => {
|
||||
this.showMessage(`Whale oil: ${this.inventory.whaleOil} barrels. Your precious cargo!`);
|
||||
});
|
||||
|
||||
// Penguin cage (dark humor ahead)
|
||||
const penguinCage = this.add.rectangle(650, 350, 80, 80, 0x333333);
|
||||
penguinCage.setInteractive({ useHandCursor: true });
|
||||
penguinCage.setStrokeStyle(3, 0x000000);
|
||||
|
||||
this.add.text(650, 350, '🐧', {
|
||||
fontSize: '32px'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
penguinCage.on('pointerdown', () => {
|
||||
if (this.inventory.penguins > 0) {
|
||||
this.showMessage(`${this.inventory.penguins} penguins. They're... emergency fuel. Dark times call for dark measures.`);
|
||||
} else {
|
||||
this.showMessage('Empty penguin cage. Should we catch some for... fuel?');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
createWheel() {
|
||||
// Ship's wheel
|
||||
const wheel = this.add.circle(550, 200, 40, 0x8B4513);
|
||||
wheel.setInteractive({ useHandCursor: true });
|
||||
wheel.setStrokeStyle(4, 0x654321);
|
||||
|
||||
// Wheel spokes
|
||||
for (let i = 0; i < 8; i++) {
|
||||
const angle = (i * 45) * Math.PI / 180;
|
||||
const x1 = 550 + Math.cos(angle) * 15;
|
||||
const y1 = 200 + Math.sin(angle) * 15;
|
||||
const x2 = 550 + Math.cos(angle) * 35;
|
||||
const y2 = 200 + Math.sin(angle) * 35;
|
||||
this.add.line(0, 0, x1, y1, x2, y2, 0x654321).setLineWidth(3);
|
||||
}
|
||||
|
||||
wheel.on('pointerdown', () => {
|
||||
// Open the map scene
|
||||
this.scene.start('MapScene', { inventory: this.inventory });
|
||||
});
|
||||
}
|
||||
|
||||
createInventoryDisplay() {
|
||||
// Inventory panel
|
||||
const panel = this.add.rectangle(80, 80, 140, 100, 0x000000, 0.7);
|
||||
panel.setStrokeStyle(2, 0xffffff);
|
||||
|
||||
this.inventoryText = this.add.text(20, 40, '', {
|
||||
fontSize: '14px',
|
||||
fill: '#fff'
|
||||
});
|
||||
|
||||
this.updateInventoryDisplay();
|
||||
}
|
||||
|
||||
updateInventoryDisplay() {
|
||||
this.inventoryText.setText([
|
||||
'Inventory:',
|
||||
`Fuel: ${this.inventory.fuel}`,
|
||||
`Oil: ${this.inventory.whaleOil}`,
|
||||
`Penguins: ${this.inventory.penguins}`
|
||||
]);
|
||||
}
|
||||
|
||||
createMessageBox() {
|
||||
// Message display area
|
||||
this.messageBox = this.add.rectangle(400, 500, 760, 80, 0x000000, 0.8);
|
||||
this.messageBox.setStrokeStyle(2, 0xcccccc);
|
||||
|
||||
this.messageText = this.add.text(400, 500, 'Welcome aboard! Click around to explore the ship.', {
|
||||
fontSize: '16px',
|
||||
fill: '#fff',
|
||||
wordWrap: { width: 740 },
|
||||
align: 'center'
|
||||
}).setOrigin(0.5);
|
||||
}
|
||||
|
||||
showMessage(message) {
|
||||
this.messageText.setText(message);
|
||||
}
|
||||
|
||||
// Helper method to modify inventory (for future use)
|
||||
addToInventory(item, amount) {
|
||||
if (this.inventory.hasOwnProperty(item)) {
|
||||
this.inventory[item] += amount;
|
||||
this.updateInventoryDisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user