feat: add player Names Throughout the Game UI
This commit is contained in:
+22
-12
@@ -67,8 +67,8 @@
|
||||
return item;
|
||||
};
|
||||
ui.availability.replaceChildren(
|
||||
availabilityItem(`Игрок 1: ${info.player1Available ? 'свободен' : 'занят'}`),
|
||||
availabilityItem(`Игрок 2: ${info.player2Available ? 'свободен' : 'занят'}`),
|
||||
availabilityItem(`Игрок 1: ${info.player1Available ? 'свободен' : role === 'player1' ? 'Вы' : info.player1Name || 'занят'}`),
|
||||
availabilityItem(`Игрок 2: ${info.player2Available ? 'свободен' : role === 'player2' ? 'Вы' : info.player2Name || 'занят'}`),
|
||||
availabilityItem(`зрительских мест: ${info.spectatorsAvailable}`),
|
||||
);
|
||||
if (state?.phase === 'lobby') renderLobby();
|
||||
@@ -110,6 +110,7 @@
|
||||
payload.boards.every(board => typeof board === 'string' && /^[01234]{100}$/.test(board)) &&
|
||||
typeof payload.version === 'number' && typeof payload.gameId === 'number' &&
|
||||
(payload.winner === null || payload.winner === 0 || payload.winner === 1) && Array.isArray(payload.statistics) &&
|
||||
Array.isArray(payload.players) && payload.players.length === 2 && payload.players.every(name => typeof name === 'string' && name.length <= 80) &&
|
||||
payload.statistics.length === 2 && payload.statistics.every(entry => Array.isArray(entry) && entry.length === 4 &&
|
||||
entry.every(value => Number.isInteger(value) && value >= 0));
|
||||
}
|
||||
@@ -134,7 +135,14 @@
|
||||
target.x >= 0 && target.x < 10 && target.y >= 0 && target.y < 10 &&
|
||||
state.boards[opponentIndex()][target.y * 10 + target.x] === '0';
|
||||
}
|
||||
function playerLabel(index) { return index === 1 && state?.mode === 'bot' ? 'ESP32' : `Игрок ${index + 1}`; }
|
||||
function playerName(index) {
|
||||
const name = state?.players?.[index];
|
||||
return typeof name === 'string' && name.trim() ? name : `Игрок ${index + 1}`;
|
||||
}
|
||||
function playerLabel(index) {
|
||||
if (index === 1 && state?.mode === 'bot') return 'ESP32';
|
||||
return isPlayer() && index === ownIndex() ? 'Вы' : playerName(index);
|
||||
}
|
||||
|
||||
async function fireTarget(target) {
|
||||
if (!canFireTarget(target)) return false;
|
||||
@@ -221,12 +229,12 @@
|
||||
|
||||
function boardDefinitions(result = false) {
|
||||
if (role === 'spectator' || result) return [
|
||||
{ index: 0, title: 'Поле игрока 1', key: 'player1', targetable: false },
|
||||
{ index: 1, title: 'Поле игрока 2', key: 'player2', targetable: false }
|
||||
{ index: 0, title: `Поле: ${playerLabel(0)}`, key: 'player1', targetable: false },
|
||||
{ index: 1, title: `Поле: ${playerLabel(1)}`, key: 'player2', targetable: false }
|
||||
];
|
||||
return [
|
||||
{ index: ownIndex(), title: 'Моё поле', key: 'own', targetable: false },
|
||||
{ index: opponentIndex(), title: state.mode === 'bot' ? 'Поле ESP32' : 'Поле соперника', key: 'opponent', targetable: canShoot() }
|
||||
{ index: opponentIndex(), title: state.mode === 'bot' ? 'Поле ESP32' : `Поле: ${playerName(opponentIndex())}`, key: 'opponent', targetable: canShoot() }
|
||||
];
|
||||
}
|
||||
|
||||
@@ -242,7 +250,8 @@
|
||||
ui.tabs.replaceChildren();
|
||||
definitions.forEach(definition => {
|
||||
const tab = document.createElement('button');
|
||||
tab.type = 'button'; tab.role = 'tab'; tab.textContent = definition.title;
|
||||
tab.type = 'button'; tab.role = 'tab'; tab.textContent = definition.key === 'opponent' ? playerLabel(definition.index) : definition.title;
|
||||
tab.title = definition.title; tab.setAttribute('aria-label', definition.title);
|
||||
tab.setAttribute('aria-selected', String(definition.key === activeBoard));
|
||||
tab.addEventListener('click', () => { activeBoard = definition.key; renderGame(); });
|
||||
ui.tabs.append(tab);
|
||||
@@ -253,7 +262,8 @@
|
||||
function renderLobby() {
|
||||
showScreen('lobby');
|
||||
const playerOne = role === 'player1';
|
||||
ui.lobbyDescription.textContent = role === 'spectator' ? 'Вы наблюдаете за подготовкой партии.' : 'Ожидайте готовности партии или настройте режим.';
|
||||
const opponent = state.mode === 'bot' ? 'ESP32' : playerName(opponentIndex());
|
||||
ui.lobbyDescription.textContent = role === 'spectator' ? 'Вы наблюдаете за подготовкой партии.' : state.mode === 'human' && info?.player2Available ? 'Ожидаем соперника.' : `Ожидаем готовности ${opponent}.`;
|
||||
ui.modeControls.hidden = !playerOne;
|
||||
if (playerOne) startLobbyInfoPolling();
|
||||
else stopLobbyInfoPolling();
|
||||
@@ -265,8 +275,8 @@
|
||||
button.disabled = !playerOne;
|
||||
});
|
||||
ui.start.disabled = !canStart;
|
||||
ui.modeDescription.textContent = state.mode === 'human' ? (playerTwoReady ? 'Второй игрок готов. Можно начать партию.' : 'Ожидаем подключения второго игрока.') : 'Игра против ESP32. Можно начать сразу.';
|
||||
ui.lobbyHelp.textContent = playerOne ? '' : 'Игрок 1 выбирает режим и запускает партию.';
|
||||
ui.modeDescription.textContent = state.mode === 'human' ? (playerTwoReady ? `${playerName(1)} готов. Можно начать партию.` : 'Ожидаем соперника.') : 'Игра против ESP32. Можно начать сразу.';
|
||||
ui.lobbyHelp.textContent = playerOne ? '' : `${playerName(0)} выбирает режим и запускает партию.`;
|
||||
}
|
||||
|
||||
function renderGame() {
|
||||
@@ -275,7 +285,7 @@
|
||||
showScreen('game');
|
||||
if (canShoot() && !selectedTarget) activeBoard = 'opponent';
|
||||
ui.turn.textContent = canShoot() ? 'Ваш ход' : `Ходит ${playerLabel(state.turn === 'player2' ? 1 : 0)}`;
|
||||
ui.wins.textContent = `Победы: ${state.wins[0]} : ${state.wins[1]}`;
|
||||
ui.wins.textContent = `${playerLabel(0)} ${state.wins[0]} : ${state.wins[1]} ${playerLabel(1)}`;
|
||||
renderBoards(ui.boards);
|
||||
const available = canShoot();
|
||||
ui.shotControls.hidden = !isPlayer();
|
||||
@@ -291,7 +301,7 @@
|
||||
showScreen('result');
|
||||
if (statisticsGameId !== state.gameId) refreshStatistics();
|
||||
const waiting = state.phase === 'rematch_wait';
|
||||
const winner = state.winner === 0 || state.winner === 1 ? `Победил ${playerLabel(state.winner)}. ` : '';
|
||||
const winner = state.winner === ownIndex() && isPlayer() ? 'Вы победили. ' : state.winner === 0 || state.winner === 1 ? `Победил ${playerLabel(state.winner)}. ` : '';
|
||||
const matchSummary = state.statistics.map((entry, index) => `${playerLabel(index)}: выстрелы ${entry[0]}, попадания ${entry[1]}, промахи ${entry[2]}, потоплено ${entry[3]}.`).join(' ');
|
||||
const cumulative = cumulativeStatistics?.cumulative?.map((entry, index) => `${playerLabel(index)} всего: игр ${entry[0]}, побед ${entry[1]}, поражений ${entry[2]}, выстрелов ${entry[4]}, попаданий ${entry[5]}, промахов ${entry[6]}, потоплено ${entry[3]}.`).join(' ') || '';
|
||||
ui.result.textContent = `${winner}${matchSummary} ${cumulative} ${waiting ? 'Ожидается подтверждение повторной игры.' : 'Поля раскрыты. Можно подтвердить повторную игру.'}`;
|
||||
|
||||
Reference in New Issue
Block a user