Render authenticated multiplayer presence
This commit is contained in:
parent
7b90701434
commit
74ecc68b17
@ -144,6 +144,8 @@ class GameScene extends Phaser.Scene {
|
|||||||
this.tradeDeliveries = 0;
|
this.tradeDeliveries = 0;
|
||||||
this.tradeLosses = 0;
|
this.tradeLosses = 0;
|
||||||
this.playerTradeLosses = 0;
|
this.playerTradeLosses = 0;
|
||||||
|
this.remotePlayers = new Map();
|
||||||
|
this.multiplayerSendAccumulatorMs = 0;
|
||||||
|
|
||||||
airshipLog('scene:init', {
|
airshipLog('scene:init', {
|
||||||
hull: this.playerHull,
|
hull: this.playerHull,
|
||||||
@ -182,6 +184,11 @@ class GameScene extends Phaser.Scene {
|
|||||||
this.player.setFrame(0);
|
this.player.setFrame(0);
|
||||||
this.createPlayerSmoke();
|
this.createPlayerSmoke();
|
||||||
|
|
||||||
|
this.handleMultiplayerSnapshot = (event) => {
|
||||||
|
this.syncRemotePlayers(event.detail?.players || []);
|
||||||
|
};
|
||||||
|
window.addEventListener('airship:multiplayer-snapshot', this.handleMultiplayerSnapshot);
|
||||||
|
|
||||||
this.pirates = this.physics.add.group();
|
this.pirates = this.physics.add.group();
|
||||||
this.merchants = this.physics.add.group();
|
this.merchants = this.physics.add.group();
|
||||||
this.playerShots = this.physics.add.group();
|
this.playerShots = this.physics.add.group();
|
||||||
@ -276,6 +283,12 @@ class GameScene extends Phaser.Scene {
|
|||||||
registerDebugSnapshot(null);
|
registerDebugSnapshot(null);
|
||||||
window.removeEventListener('airship:helm-vector', this.handleHelmVector);
|
window.removeEventListener('airship:helm-vector', this.handleHelmVector);
|
||||||
window.removeEventListener('airship:action', this.handleMobileAction);
|
window.removeEventListener('airship:action', this.handleMobileAction);
|
||||||
|
window.removeEventListener('airship:multiplayer-snapshot', this.handleMultiplayerSnapshot);
|
||||||
|
for (const remote of this.remotePlayers.values()) {
|
||||||
|
remote.sprite?.destroy();
|
||||||
|
remote.label?.destroy();
|
||||||
|
}
|
||||||
|
this.remotePlayers.clear();
|
||||||
airshipLog('scene:shutdown', {
|
airshipLog('scene:shutdown', {
|
||||||
gameState: this.gameState,
|
gameState: this.gameState,
|
||||||
hull: this.playerHull,
|
hull: this.playerHull,
|
||||||
@ -1401,6 +1414,7 @@ class GameScene extends Phaser.Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.updateProgressionInteraction();
|
this.updateProgressionInteraction();
|
||||||
|
this.updateMultiplayer(deltaMs);
|
||||||
if (this.dockOpen) {
|
if (this.dockOpen) {
|
||||||
this.player.setVelocity(0, 0);
|
this.player.setVelocity(0, 0);
|
||||||
const hudState = this.buildHudState();
|
const hudState = this.buildHudState();
|
||||||
@ -1437,6 +1451,85 @@ class GameScene extends Phaser.Scene {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
syncRemotePlayers(players = []) {
|
||||||
|
const seen = new Set();
|
||||||
|
|
||||||
|
for (const state of players) {
|
||||||
|
if (!state?.id) continue;
|
||||||
|
seen.add(state.id);
|
||||||
|
|
||||||
|
let remote = this.remotePlayers.get(state.id);
|
||||||
|
if (!remote) {
|
||||||
|
const sprite = this.add.sprite(
|
||||||
|
Number(state.x) || this.world.spawn.x,
|
||||||
|
Number(state.y) || this.world.spawn.y,
|
||||||
|
'player-airship',
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
sprite
|
||||||
|
.setDepth(5.5)
|
||||||
|
.setDisplaySize(60, 114)
|
||||||
|
.setTint(0x8cd3ff)
|
||||||
|
.setAlpha(0.86);
|
||||||
|
sprite.play('player-forward');
|
||||||
|
sprite.anims.timeScale = 0.72;
|
||||||
|
|
||||||
|
const label = this.add.text(sprite.x, sprite.y - 70, state.name || 'CAPTAIN', {
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
fontSize: '10px',
|
||||||
|
color: '#bfe6ff',
|
||||||
|
backgroundColor: '#071018aa',
|
||||||
|
padding: { x: 4, y: 2 },
|
||||||
|
}).setOrigin(0.5).setDepth(12);
|
||||||
|
|
||||||
|
remote = {
|
||||||
|
sprite,
|
||||||
|
label,
|
||||||
|
targetX: sprite.x,
|
||||||
|
targetY: sprite.y,
|
||||||
|
targetAngle: Number(state.angle) || 0,
|
||||||
|
hull: Number(state.hull) || 100,
|
||||||
|
};
|
||||||
|
this.remotePlayers.set(state.id, remote);
|
||||||
|
}
|
||||||
|
|
||||||
|
remote.targetX = clamp(Number(state.x) || 0, 0, this.world.width);
|
||||||
|
remote.targetY = clamp(Number(state.y) || 0, 0, this.world.height);
|
||||||
|
remote.targetAngle = normalizeDegrees(Number(state.angle) || 0);
|
||||||
|
remote.hull = Math.max(0, Number(state.hull) || 0);
|
||||||
|
remote.label.setText(`${state.name || 'CAPTAIN'} ${Math.round(remote.hull)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [id, remote] of this.remotePlayers) {
|
||||||
|
if (seen.has(id)) continue;
|
||||||
|
remote.sprite?.destroy();
|
||||||
|
remote.label?.destroy();
|
||||||
|
this.remotePlayers.delete(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMultiplayer(deltaMs) {
|
||||||
|
this.multiplayerSendAccumulatorMs += deltaMs;
|
||||||
|
if (this.multiplayerSendAccumulatorMs >= 100) {
|
||||||
|
this.multiplayerSendAccumulatorMs %= 100;
|
||||||
|
window.airshipMultiplayer?.sendState?.({
|
||||||
|
x: this.player?.x || 0,
|
||||||
|
y: this.player?.y || 0,
|
||||||
|
angle: this.player?.angle || 0,
|
||||||
|
hull: this.playerHull,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const remote of this.remotePlayers.values()) {
|
||||||
|
const sprite = remote.sprite;
|
||||||
|
if (!sprite?.active) continue;
|
||||||
|
sprite.x = Phaser.Math.Linear(sprite.x, remote.targetX, 0.32);
|
||||||
|
sprite.y = Phaser.Math.Linear(sprite.y, remote.targetY, 0.32);
|
||||||
|
sprite.angle += signedAngleDelta(remote.targetAngle, sprite.angle) * 0.32;
|
||||||
|
remote.label.setPosition(sprite.x, sprite.y - 70);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updatePlayer(dt, deltaMs) {
|
updatePlayer(dt, deltaMs) {
|
||||||
if (!this.player?.body) return;
|
if (!this.player?.body) return;
|
||||||
const stats = this.playerStats || deriveShipStats(this.progression?.loadout, this.progression?.installedConditions);
|
const stats = this.playerStats || deriveShipStats(this.progression?.loadout, this.progression?.installedConditions);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user