feat: add client entry point, boot scene, and socket client
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import Phaser from 'phaser';
|
||||
import { BootScene } from './scenes/BootScene.js';
|
||||
import { GameScene } from './scenes/GameScene.js';
|
||||
|
||||
const config: Phaser.Types.Core.GameConfig = {
|
||||
type: Phaser.AUTO,
|
||||
parent: 'game',
|
||||
width: 800,
|
||||
height: 600,
|
||||
backgroundColor: '#1a1a2e',
|
||||
pixelArt: true,
|
||||
scene: [BootScene, GameScene],
|
||||
};
|
||||
|
||||
new Phaser.Game(config);
|
||||
@@ -0,0 +1,51 @@
|
||||
import { io, Socket } from 'socket.io-client';
|
||||
import type { ServerEvents, ClientEvents, WorldState, StateUpdate, PlayerJoined, PlayerLeft, PlayerInput } from '@dflike/shared';
|
||||
|
||||
type TypedSocket = Socket<ServerEvents, ClientEvents>;
|
||||
|
||||
export class SocketClient {
|
||||
private socket: TypedSocket;
|
||||
private _playerId: string | null = null;
|
||||
private _entityId: number | null = null;
|
||||
|
||||
// Event callbacks
|
||||
onWorldState: ((data: WorldState) => void) | null = null;
|
||||
onStateUpdate: ((data: StateUpdate) => void) | null = null;
|
||||
onPlayerJoined: ((data: PlayerJoined) => void) | null = null;
|
||||
onPlayerLeft: ((data: PlayerLeft) => void) | null = null;
|
||||
|
||||
constructor(url: string) {
|
||||
this.socket = io(url);
|
||||
|
||||
this.socket.on('world-state', (data) => {
|
||||
this.onWorldState?.(data);
|
||||
});
|
||||
|
||||
this.socket.on('state-update', (data) => {
|
||||
this.onStateUpdate?.(data);
|
||||
});
|
||||
|
||||
this.socket.on('player-joined', (data) => {
|
||||
if (!this._playerId) {
|
||||
this._playerId = data.playerId;
|
||||
this._entityId = data.entityId;
|
||||
}
|
||||
this.onPlayerJoined?.(data);
|
||||
});
|
||||
|
||||
this.socket.on('player-left', (data) => {
|
||||
this.onPlayerLeft?.(data);
|
||||
});
|
||||
}
|
||||
|
||||
get playerId(): string | null { return this._playerId; }
|
||||
get entityId(): number | null { return this._entityId; }
|
||||
|
||||
sendInput(input: PlayerInput): void {
|
||||
this.socket.emit('player-input', input);
|
||||
}
|
||||
|
||||
disconnect(): void {
|
||||
this.socket.disconnect();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import Phaser from 'phaser';
|
||||
import { SocketClient } from '../network/SocketClient.js';
|
||||
import type { WorldState } from '@dflike/shared';
|
||||
|
||||
export class BootScene extends Phaser.Scene {
|
||||
private client!: SocketClient;
|
||||
|
||||
constructor() {
|
||||
super({ key: 'BootScene' });
|
||||
}
|
||||
|
||||
create(): void {
|
||||
const statusText = this.add.text(
|
||||
this.cameras.main.centerX,
|
||||
this.cameras.main.centerY,
|
||||
'Connecting to server...',
|
||||
{ fontSize: '24px', color: '#ffffff' }
|
||||
).setOrigin(0.5);
|
||||
|
||||
const serverUrl = 'http://localhost:3001';
|
||||
this.client = new SocketClient(serverUrl);
|
||||
|
||||
this.client.onWorldState = (worldState: WorldState) => {
|
||||
statusText.setText('Connected! Loading game...');
|
||||
this.scene.start('GameScene', {
|
||||
client: this.client,
|
||||
worldState,
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import Phaser from 'phaser';
|
||||
|
||||
export class GameScene extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'GameScene' });
|
||||
}
|
||||
|
||||
init(_data: unknown): void {}
|
||||
create(): void {
|
||||
this.add.text(100, 100, 'Game scene loaded', { color: '#ffffff' });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user