Skip to content

Commit 0ffa269

Browse files
committed
fix path resolution
1 parent cfb9d85 commit 0ffa269

File tree

3 files changed

+153
-55
lines changed

3 files changed

+153
-55
lines changed

client/src/commit_time.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2026-01-28T19:57:36.233Z
1+
2026-01-28T20:03:33.159Z

client/src/ship.ts

Lines changed: 139 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,109 +2,202 @@
22
* Ship Game - A 2D Phaser game
33
*
44
* Entry point for the ship game accessible at /ship
5+
* A cruise ship game where you can move between different decks
56
*/
67

78
import Phaser from 'phaser';
89

910
/**
10-
* Main game scene for the ship game
11+
* Deck names for the cruise ship
12+
*/
13+
const DECK_NAMES = [
14+
'Sun Deck',
15+
'Pool Deck',
16+
'Promenade Deck',
17+
'Main Deck',
18+
'Lower Deck',
19+
'Engine Deck'
20+
];
21+
22+
/**
23+
* Main game scene for the cruise ship game
1124
*/
1225
class ShipScene extends Phaser.Scene {
13-
private ship: Phaser.GameObjects.Sprite | null = null;
26+
private player: Phaser.GameObjects.Sprite | null = null;
1427
private cursors: Phaser.Types.Input.Keyboard.CursorKeys | null = null;
1528
private wasdKeys: Record<string, Phaser.Input.Keyboard.Key> | null = null;
29+
private pageUpKey: Phaser.Input.Keyboard.Key | null = null;
30+
private pageDownKey: Phaser.Input.Keyboard.Key | null = null;
31+
private currentDeck = 0;
32+
private deckDisplay: Phaser.GameObjects.Text | null = null;
33+
private deckLayers: Phaser.GameObjects.Container[] = [];
34+
private pageUpPressed = false;
35+
private pageDownPressed = false;
1636
private readonly shipSpeed = 200;
37+
private readonly totalDecks = DECK_NAMES.length;
1738

1839
constructor() {
1940
super({ key: 'ShipScene' });
2041
}
2142

2243
create(): void {
23-
// Set background color
24-
this.cameras.main.setBackgroundColor('#1a1a2e');
44+
// Set background color (ocean blue)
45+
this.cameras.main.setBackgroundColor('#0a1929');
46+
47+
// Create deck layers
48+
this.createDeckLayers();
2549

26-
// Create a simple ship sprite (using a rectangle for now)
27-
// In a real game, you'd load an image asset
50+
// Create player sprite (person walking on deck)
2851
const graphics = this.add.graphics();
2952
graphics.fillStyle(0x00ff00);
30-
graphics.fillTriangle(0, -20, -15, 15, 15, 15);
31-
graphics.generateTexture('ship', 30, 30);
53+
graphics.fillCircle(0, 0, 10);
54+
graphics.fillStyle(0x0000ff);
55+
graphics.fillRect(-5, 5, 10, 15);
56+
graphics.generateTexture('player', 20, 25);
3257
graphics.destroy();
3358

34-
// Create ship sprite at center
35-
this.ship = this.add.sprite(400, 300, 'ship');
36-
this.ship.setOrigin(0.5, 0.5);
59+
// Create player sprite at center of current deck
60+
this.player = this.add.sprite(400, 300, 'player');
61+
this.player.setOrigin(0.5, 0.5);
3762

3863
// Set up keyboard input
3964
this.cursors = this.input.keyboard?.createCursorKeys() || null;
4065

41-
// Add WASD keys as alternative
66+
// Add WASD keys for horizontal movement
4267
if (this.input.keyboard) {
43-
this.wasdKeys = this.input.keyboard.addKeys('W,S,A,D') as Record<string, Phaser.Input.Keyboard.Key>;
68+
this.wasdKeys = this.input.keyboard.addKeys('A,D') as Record<string, Phaser.Input.Keyboard.Key>;
69+
// Page Up/Down for deck switching
70+
this.pageUpKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.PAGE_UP);
71+
this.pageDownKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.PAGE_DOWN);
4472
}
4573

74+
// Create deck display text
75+
this.deckDisplay = this.add.text(10, 10, '', {
76+
fontSize: '18px',
77+
color: '#ffffff',
78+
backgroundColor: '#000000',
79+
padding: { x: 15, y: 10 }
80+
});
81+
this.deckDisplay.setScrollFactor(0);
82+
this.updateDeckDisplay();
83+
4684
// Add instructions text
47-
const instructions = this.add.text(10, 10, 'Ship Game\nArrow Keys or WASD to move', {
48-
fontSize: '16px',
85+
const instructions = this.add.text(10, 70, 'Cruise Ship Game\nLeft/Right or A/D to move\nPage Up/Down to change decks', {
86+
fontSize: '14px',
4987
color: '#ffffff',
5088
backgroundColor: '#000000',
51-
padding: { x: 10, y: 5 }
89+
padding: { x: 10, y: 8 }
5290
});
5391
instructions.setScrollFactor(0);
92+
93+
// Show current deck
94+
this.showDeck(this.currentDeck);
95+
}
96+
97+
createDeckLayers(): void {
98+
// Create visual layers for each deck
99+
for (let i = 0; i < this.totalDecks; i++) {
100+
const container = this.add.container(0, 0);
101+
102+
// Create deck floor (different colors for each deck)
103+
const deckColor = 0x2a4a6a + (i * 0x101010);
104+
const floor = this.add.rectangle(400, 550, 800, 100, deckColor);
105+
floor.setAlpha(0.7);
106+
container.add(floor);
107+
108+
// Add deck number label
109+
const label = this.add.text(50, 520, `Deck ${i + 1}: ${DECK_NAMES[i]}`, {
110+
fontSize: '16px',
111+
color: '#ffffff',
112+
backgroundColor: '#000000',
113+
padding: { x: 8, y: 4 }
114+
});
115+
container.add(label);
116+
117+
// Add some decorative elements (windows, railings, etc.)
118+
for (let j = 0; j < 10; j++) {
119+
const window = this.add.rectangle(100 + j * 70, 500, 40, 30, 0x87ceeb);
120+
window.setAlpha(0.5);
121+
container.add(window);
122+
}
123+
124+
// Initially hide all decks except the first
125+
container.setVisible(i === 0);
126+
this.deckLayers.push(container);
127+
}
128+
}
129+
130+
updateDeckDisplay(): void {
131+
if (this.deckDisplay) {
132+
this.deckDisplay.setText(`Deck ${this.currentDeck + 1}/${this.totalDecks}: ${DECK_NAMES[this.currentDeck]}`);
133+
}
134+
}
135+
136+
showDeck(deckIndex: number): void {
137+
// Hide all decks
138+
this.deckLayers.forEach((layer, index) => {
139+
layer.setVisible(index === deckIndex);
140+
});
141+
this.updateDeckDisplay();
142+
}
143+
144+
changeDeck(direction: number): void {
145+
const newDeck = this.currentDeck + direction;
146+
if (newDeck >= 0 && newDeck < this.totalDecks) {
147+
this.currentDeck = newDeck;
148+
this.showDeck(this.currentDeck);
149+
}
54150
}
55151

56152
update(): void {
57-
if (!this.ship || !this.cursors) {
153+
if (!this.player || !this.cursors) {
58154
return;
59155
}
60156

157+
// Handle deck switching (only trigger once per key press)
158+
if (this.pageUpKey?.isDown && !this.pageUpPressed) {
159+
this.pageUpPressed = true;
160+
this.changeDeck(-1);
161+
} else if (!this.pageUpKey?.isDown) {
162+
this.pageUpPressed = false;
163+
}
164+
165+
if (this.pageDownKey?.isDown && !this.pageDownPressed) {
166+
this.pageDownPressed = true;
167+
this.changeDeck(1);
168+
} else if (!this.pageDownKey?.isDown) {
169+
this.pageDownPressed = false;
170+
}
171+
61172
const delta = this.game.loop.delta;
62173

63-
// Calculate movement
174+
// Calculate horizontal movement only
64175
let velocityX = 0;
65-
let velocityY = 0;
66176

67-
// Check arrow keys or WASD
177+
// Check arrow keys or WASD (only left/right)
68178
const left = this.cursors.left?.isDown || this.wasdKeys?.A?.isDown || false;
69179
const right = this.cursors.right?.isDown || this.wasdKeys?.D?.isDown || false;
70-
const up = this.cursors.up?.isDown || this.wasdKeys?.W?.isDown || false;
71-
const down = this.cursors.down?.isDown || this.wasdKeys?.S?.isDown || false;
72180

73181
if (left) {
74182
velocityX = -this.shipSpeed;
75183
} else if (right) {
76184
velocityX = this.shipSpeed;
77185
}
78186

79-
if (up) {
80-
velocityY = -this.shipSpeed;
81-
} else if (down) {
82-
velocityY = this.shipSpeed;
83-
}
84-
85-
// Normalize diagonal movement
86-
if (velocityX !== 0 && velocityY !== 0) {
87-
const length = Math.sqrt(velocityX * velocityX + velocityY * velocityY);
88-
velocityX = (velocityX / length) * this.shipSpeed;
89-
velocityY = (velocityY / length) * this.shipSpeed;
90-
}
91-
92-
// Update ship position
187+
// Update player position
93188
const deltaSeconds = delta / 1000;
94-
this.ship.x += velocityX * deltaSeconds;
95-
this.ship.y += velocityY * deltaSeconds;
189+
this.player.x += velocityX * deltaSeconds;
96190

97-
// Rotate ship to face movement direction
98-
if (velocityX !== 0 || velocityY !== 0) {
99-
const angle = Math.atan2(velocityY, velocityX) * (180 / Math.PI) + 90;
100-
this.ship.rotation = Phaser.Math.DegToRad(angle);
191+
// Rotate player to face movement direction
192+
if (velocityX < 0) {
193+
this.player.setFlipX(true);
194+
} else if (velocityX > 0) {
195+
this.player.setFlipX(false);
101196
}
102197

103-
// Keep ship within bounds
198+
// Keep player within bounds (horizontal only)
104199
const width = this.cameras.main.width;
105-
const height = this.cameras.main.height;
106-
this.ship.x = Phaser.Math.Clamp(this.ship.x, 0, width);
107-
this.ship.y = Phaser.Math.Clamp(this.ship.y, 0, height);
200+
this.player.x = Phaser.Math.Clamp(this.player.x, 20, width - 20);
108201
}
109202
}
110203

server/src/main.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,19 @@ async fn websocket_handler(ws: WebSocketUpgrade, State(state): State<AppState>)
224224
///
225225
/// Serves the ship.html file for the Phaser 2D game.
226226
async fn ship_handler() -> Result<Html<String>, Response> {
227-
match fs::read_to_string("client/dist/ship.html") {
228-
Ok(html) => Ok(Html(html)),
229-
Err(_) => {
230-
// Fallback: try reading from source during development
231-
match fs::read_to_string("client/ship.html") {
232-
Ok(html) => Ok(Html(html)),
233-
Err(_) => Err((StatusCode::NOT_FOUND, "Ship game not found").into_response()),
234-
}
227+
// Try multiple possible paths depending on where the server is run from
228+
let paths = [
229+
"client/dist/ship.html", // From project root
230+
"../client/dist/ship.html", // From server/ directory
231+
"client/ship.html", // Source file from project root
232+
"../client/ship.html", // Source file from server/ directory
233+
];
234+
235+
for path in &paths {
236+
if let Ok(html) = fs::read_to_string(path) {
237+
return Ok(Html(html));
235238
}
236239
}
240+
241+
Err((StatusCode::NOT_FOUND, "Ship game not found").into_response())
237242
}

0 commit comments

Comments
 (0)