mapa
This commit is contained in:
129
src/systems/MultiplayerSystem.js
Normal file
129
src/systems/MultiplayerSystem.js
Normal file
@@ -0,0 +1,129 @@
|
||||
class MultiplayerSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.socket = null;
|
||||
this.otherPlayers = {}; // Map socketId -> Sprite
|
||||
this.isConnected = false;
|
||||
|
||||
// Try to connect
|
||||
this.connect();
|
||||
}
|
||||
|
||||
connect() {
|
||||
if (typeof io === 'undefined') {
|
||||
console.warn('⚠️ Socket.IO not found. Multiplayer disabled.');
|
||||
console.warn('Please run: npm install socket.io-client OR include CDN.');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('🌐 Connecting to Multiplayer Server...');
|
||||
// Connect to localhost:3000
|
||||
this.socket = io('http://localhost:3000');
|
||||
|
||||
this.socket.on('connect', () => {
|
||||
console.log('✅ Connected to Server! ID:', this.socket.id);
|
||||
this.isConnected = true;
|
||||
|
||||
// Send initial pos
|
||||
if (this.scene.player) {
|
||||
const pos = this.scene.player.getPosition();
|
||||
this.socket.emit('playerMovement', {
|
||||
x: pos.x,
|
||||
y: pos.y,
|
||||
anim: 'idle',
|
||||
flipX: false
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.socket.on('currentPlayers', (players) => {
|
||||
Object.keys(players).forEach((id) => {
|
||||
if (id === this.socket.id) return;
|
||||
this.addOtherPlayer(players[id]);
|
||||
});
|
||||
});
|
||||
|
||||
this.socket.on('newPlayer', (playerInfo) => {
|
||||
this.addOtherPlayer(playerInfo);
|
||||
});
|
||||
|
||||
this.socket.on('playerDisconnected', (playerId) => {
|
||||
this.removeOtherPlayer(playerId);
|
||||
});
|
||||
|
||||
this.socket.on('playerMoved', (playerInfo) => {
|
||||
if (this.otherPlayers[playerInfo.id]) {
|
||||
const sprite = this.otherPlayers[playerInfo.id];
|
||||
// Update target pos for interpolation (TODO: logic)
|
||||
// For now direct teleport
|
||||
|
||||
// Convert grid to screen
|
||||
const iso = new IsometricUtils(48, 24);
|
||||
const screen = iso.toScreen(playerInfo.x, playerInfo.y);
|
||||
|
||||
sprite.setPosition(screen.x + this.scene.terrainOffsetX, screen.y + this.scene.terrainOffsetY);
|
||||
sprite.setDepth(sprite.y);
|
||||
|
||||
// Anim/Flip logic could go here
|
||||
if (playerInfo.flipX !== undefined) sprite.setFlipX(playerInfo.flipX);
|
||||
}
|
||||
});
|
||||
|
||||
this.socket.on('worldAction', (action) => {
|
||||
// Handle world syncing
|
||||
if (action.type === 'build' && this.scene.buildingSystem) {
|
||||
// Hacky: place building remotely
|
||||
// this.scene.terrainSystem.placeStructure(...)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addOtherPlayer(playerInfo) {
|
||||
if (this.otherPlayers[playerInfo.id]) return;
|
||||
|
||||
console.log('👤 New Player Joined:', playerInfo.id);
|
||||
|
||||
// Use player sprite
|
||||
const iso = new IsometricUtils(48, 24);
|
||||
const screen = iso.toScreen(playerInfo.x, playerInfo.y);
|
||||
|
||||
const sprite = this.scene.add.sprite(
|
||||
screen.x + this.scene.terrainOffsetX,
|
||||
screen.y + this.scene.terrainOffsetY,
|
||||
'player' // or player_idle
|
||||
);
|
||||
sprite.setOrigin(0.5, 1);
|
||||
sprite.setScale(0.3); // Same as local player
|
||||
|
||||
// Add name tag
|
||||
const text = this.scene.add.text(0, -50, 'Player', { fontSize: '12px', fill: '#ffffff' });
|
||||
text.setOrigin(0.5);
|
||||
// Container? For now just sprite, text handling is complex
|
||||
|
||||
this.otherPlayers[playerInfo.id] = sprite;
|
||||
}
|
||||
|
||||
removeOtherPlayer(playerId) {
|
||||
if (this.otherPlayers[playerId]) {
|
||||
console.log('👋 Player Left:', playerId);
|
||||
this.otherPlayers[playerId].destroy();
|
||||
delete this.otherPlayers[playerId];
|
||||
}
|
||||
}
|
||||
|
||||
update(delta) {
|
||||
if (!this.isConnected || !this.socket || !this.scene.player) return;
|
||||
|
||||
// Rate limit: send 10 times second? Or every frame?
|
||||
// Let's send only if moved
|
||||
const player = this.scene.player;
|
||||
if (player.isMoving) {
|
||||
this.socket.emit('playerMovement', {
|
||||
x: player.gridX,
|
||||
y: player.gridY,
|
||||
anim: 'walk',
|
||||
flipX: player.sprite.flipX // Accessing internal sprite
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user