/**
* PlayerInitializer - Handles safe player initialization with connection awareness
*/
export default class PlayerInitializer {
constructor(gamePeer, options = {}) {
if (!gamePeer) {
throw new Error('GamePeer instance is required');
}
this.gamePeer = gamePeer;
this.options = {
defaultPlayerName: 'Player',
defaultX: 0,
defaultY: 0,
colorPalette: [
'#FF5733', '#33FF57', '#3357FF', '#F3FF33', '#FF33F3',
'#33FFF3', '#FF33A8', '#8A33FF', '#33FF8A', '#FF8A33'
],
...options
};
this.players = {};
this.initialized = false;
this.localPlayerId = null;
}
/**
* Initialize the player system (call after room is created)
* @async
*/
async initialize() {
if (this.initialized) return;
if (!this.gamePeer.connectionManager.peer) {
throw new Error('Cannot initialize player - connection not established');
}
if (!this.gamePeer.clientId) {
throw new Error('Cannot initialize player - missing client it');
}
this.localPlayerId = `player_${this.gamePeer.clientId}`;
this.initialized = true;
}
/**
* Create and register the local player
* @async
* @returns {Promise<object>} Player data
* @throws {Error} If not initialized or connection issues
*/
async createLocalPlayer() {
if (!this.initialized) {
throw new Error('PlayerInitializer not initialized - call initialize() first');
}
if (!this.localPlayerId) {
throw new Error('Missing localPlayerId');
}
// Verify connection is ready
if (!this.gamePeer.connectionManager.peer.open) {
throw new Error('Cannot create player - connection not ready');
}
const playerData = {
name: `${this.options.defaultPlayerName} ${this.gamePeer.clientId.substr(0, 5)}`,
x: this._getRandomPosition(this.options.defaultX),
y: this._getRandomPosition(this.options.defaultY),
color: this._getRandomColor(),
id: this.localPlayerId
};
if (!this._validatePlayerData(playerData)) {
throw new Error('Invalid player data generated');
}
this.players[this.localPlayerId] = playerData;
return playerData;
}
/**
* Get current player data
* @returns {object|null} Player data or null
*/
getLocalPlayer() {
return this.players[this.localPlayerId] || null;
}
/**
* Validate player data structure
* @private
*/
_validatePlayerData(data) {
return data &&
typeof data === 'object' &&
typeof data.name === 'string' &&
typeof data.x === 'number' &&
typeof data.y === 'number' &&
typeof data.color === 'string' &&
typeof data.id === 'string';
}
/**
* Get random position near default
* @private
*/
_getRandomPosition(defaultPos) {
return defaultPos + Math.floor(Math.random() * 200 - 100);
}
/**
* Get random color from palette
* @private
*/
_getRandomColor() {
return this.options.colorPalette[
Math.floor(Math.random() * this.options.colorPalette.length)
];
}
/**
* Clean up resources
*/
destroy() {
this.players = {};
this.initialized = false;
this.localPlayerId = null;
}
}