bc/public/index.html
2025-05-13 04:14:01 +00:00

417 lines
21 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Битва: Елена vs Балард (Сетевая Версия)</title>
<link rel="stylesheet" href="style_alt.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=MedievalSharp&family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
/* --- Стили для элементов настройки игры и аутентификации --- */
.auth-game-setup-wrapper {
width: 100%;
max-width: 700px;
margin: 20px auto;
padding: 25px 30px;
background: var(--panel-bg);
border: 1px solid var(--panel-border);
border-radius: 10px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.5);
color: var(--text-light);
text-align: center;
}
/* ... (остальные стили .auth-game-setup-wrapper как были) ... */
.auth-game-setup-wrapper h2,
.auth-game-setup-wrapper h3 {
font-family: var(--font-fancy);
color: var(--text-heading);
margin-bottom: 1em;
border-bottom: 1px solid rgba(255,255,255,0.1);
padding-bottom: 0.5em;
}
.auth-game-setup-wrapper h3 {
font-size: 1.2em;
margin-top: 1.5em;
}
.auth-game-setup-wrapper button,
#auth-section form button {
font-family: var(--font-main);
background: var(--button-bg);
color: var(--button-text);
border: 1px solid rgba(0,0,0,0.3);
border-radius: 6px;
padding: 10px 18px;
margin: 8px 5px;
cursor: pointer;
transition: all 0.15s ease;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 0.5px;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
}
.auth-game-setup-wrapper button:hover:enabled,
#auth-section form button:hover:enabled {
background: var(--button-hover-bg);
transform: translateY(-2px) scale(1.02);
box-shadow: 0 4px 8px rgba(0,0,0,0.4);
}
.auth-game-setup-wrapper button:active:enabled,
#auth-section form button:active:enabled {
transform: translateY(0px) scale(1);
box-shadow: 0 1px 2px rgba(0,0,0,0.3);
}
.auth-game-setup-wrapper button:disabled,
#auth-section form button:disabled {
background: var(--button-disabled-bg);
color: var(--button-disabled-text);
cursor: not-allowed;
opacity: 0.7;
}
.auth-game-setup-wrapper input[type="text"],
#auth-section input[type="text"],
#auth-section input[type="password"] {
padding: 10px;
border-radius: 5px;
border: 1px solid var(--panel-border);
background-color: var(--bar-bg);
color: var(--text-light);
margin: 5px 5px 10px 5px;
font-size: 0.9em;
width: calc(100% - 22px); /* Учитываем padding и border */
max-width: 300px; /* Ограничиваем ширину инпутов */
box-sizing: border-box;
}
#available-games-list {
margin-top: 20px;
text-align: left;
max-height: 250px;
overflow-y: auto;
padding: 10px 15px;
background-color: rgba(0,0,0,0.25);
border: 1px solid var(--log-border);
border-radius: 6px;
}
#available-games-list ul { list-style: none; padding: 0; }
#available-games-list li {
padding: 10px;
border-bottom: 1px solid rgba(var(--log-border), 0.7);
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.9em;
}
#available-games-list li:last-child { border-bottom: none; }
#available-games-list li button {
padding: 6px 10px;
font-size: 0.8em;
margin-left: 10px;
}
#status-container { /* Для game-status-message и auth-message */
min-height: 2.5em; /* Чтобы не прыгал layout */
margin-bottom: 15px;
}
#game-status-message,
#auth-message {
color: var(--turn-color);
font-weight: bold;
font-size: 1.1em;
padding: 5px;
background-color: rgba(0,0,0,0.1);
border-radius: 4px;
display: block; /* Чтобы занимал всю ширину и не мешал */
margin-bottom: 5px; /* Небольшой отступ между сообщениями, если оба видны */
}
#auth-message.success { color: var(--heal-color, green); }
#auth-message.error { color: var(--damage-color, red); }
#auth-section form {
margin-bottom: 20px;
}
#user-info {
padding: 10px;
background-color: rgba(255,255,255,0.05);
border-radius: 5px;
margin-bottom: 20px;
}
#user-info p {
margin: 0 0 10px 0;
font-size: 1.1em;
}
#logout-button {
background: linear-gradient(145deg, #8c3a3a, #6b2b2b) !important; /* Красный для выхода */
}
#logout-button:hover {
background: linear-gradient(145deg, #a04040, #8c3a3a) !important;
}
/* --- Стили для выбора персонажа --- */
.character-selection {
margin-top: 15px;
margin-bottom: 15px;
padding: 15px;
background-color: rgba(0,0,0,0.2);
border-radius: 6px;
border: 1px solid rgba(var(--panel-border), 0.5);
}
.character-selection h4 {
font-size: 1.1em;
color: var(--text-muted);
margin-bottom: 10px;
border: none; /* Убираем нижнюю границу */
padding: 0;
}
.character-selection label {
display: inline-block;
margin: 0 15px;
cursor: pointer;
font-size: 1.05em;
padding: 5px 10px;
border-radius: 4px;
transition: background-color 0.2s ease, color 0.2s ease;
}
.character-selection input[type="radio"] {
display: none; /* Скрываем стандартные радиокнопки */
}
.character-selection input[type="radio"]:checked + label {
background-color: var(--accent-player); /* Цвет Елены для выбранного */
color: #fff;
font-weight: bold;
box-shadow: 0 0 8px rgba(108, 149, 255, 0.5);
}
/* Стилизация лейбла Альмагест при выборе */
.character-selection input[type="radio"][value="almagest"]:checked + label {
background-color: var(--accent-opponent); /* Цвет Альмагест (как у Баларда) */
box-shadow: 0 0 8px rgba(255, 108, 108, 0.5);
}
.character-selection label:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.character-selection i { /* Иконки в лейблах */
margin-right: 8px;
vertical-align: middle; /* Лучше выравнивает иконку и текст */
}
/* Цвета иконок в лейблах */
label[for="char-elena"] i { color: var(--accent-player); }
label[for="char-almagest"] i { color: var(--accent-opponent); }
</style>
</head>
<body>
<div class="auth-game-setup-wrapper"> <!-- Обертка для экранов до начала игры -->
<div id="status-container">
<div id="auth-message"></div>
<div id="game-status-message">Ожидание подключения к серверу...</div>
</div>
<div id="auth-section"> <!-- Секция Аутентификации -->
<h2>Вход / Регистрация</h2>
<form id="register-form">
<h3>Регистрация</h3>
<input type="text" id="register-username" placeholder="Имя пользователя" required autocomplete="username">
<input type="password" id="register-password" placeholder="Пароль (мин. 6 симв.)" required autocomplete="new-password">
<button type="submit">Зарегистрироваться</button>
</form>
<hr style="margin: 25px 0;">
<form id="login-form">
<h3>Вход</h3>
<input type="text" id="login-username" placeholder="Имя пользователя" required autocomplete="username">
<input type="password" id="login-password" placeholder="Пароль" required autocomplete="current-password">
<button type="submit">Войти</button>
</form>
</div>
<div id="user-info" style="display:none;"> <!-- Информация о пользователе и кнопка выхода -->
<p>Привет, <span id="logged-in-username"></span>!</p>
<button id="logout-button"><i class="fas fa-sign-out-alt"></i> Выход</button>
</div>
<div id="game-setup" style="display: none;"> <!-- Секция Настройки Игры (после логина) -->
<h2>Настройка Игры</h2>
<div>
<button id="create-ai-game">Играть против AI (Балард)</button> <!-- Уточнили против кого AI -->
</div>
<hr style="margin: 15px 0;">
<div>
<h3>PvP (Игрок против Игрока)</h3>
<!-- === Блок выбора персонажа === -->
<div class="character-selection">
<h4>Выберите персонажа для PvP:</h4>
<input type="radio" id="char-elena" name="pvp-character" value="elena" checked>
<label for="char-elena"><i class="fas fa-hat-wizard"></i> Елена</label>
<input type="radio" id="char-almagest" name="pvp-character" value="almagest">
<label for="char-almagest"><i class="fas fa-staff-aesculapius"></i> Альмагест</label> <!-- Иконка посоха -->
</div>
<!-- === Конец блока выбора персонажа === -->
<button id="create-pvp-game">Создать PvP Игру</button>
<button id="find-random-pvp-game">Найти случайную PvP Игру</button>
<br><br>
<input type="text" id="game-id-input" placeholder="Введите ID игры для присоединения">
<button id="join-pvp-game">Присоединиться к PvP по ID</button>
</div>
<div id="available-games-list">
<h3>Доступные PvP игры:</h3>
<p>Загрузка списка...</p>
<!-- Список игр будет здесь -->
</div>
</div>
</div> <!-- Конец .auth-game-setup-wrapper -->
<div class="game-wrapper" style="display: none;"> <!-- Игровая арена, изначально скрыта -->
<header class="game-header">
<!-- Заголовок будет обновляться из ui.js -->
<h1><span class="title-player">Игрок 1</span> <span class="separator"><i class="fas fa-fist-raised"></i></span> <span class="title-opponent">Игрок 2</span></h1>
</header>
<main class="battle-arena-container">
<!-- Колонка Игрока (Панель 1 в UI) -->
<div class="player-column">
<section id="player-panel" class="fighter-panel">
<div class="panel-header">
<div class="character-visual">
<!-- Аватар будет обновляться из ui.js -->
<img src="images/elena_avatar.webp" alt="Аватар игрока 1" class="avatar-image player-avatar">
</div>
<!-- Имя будет обновляться из ui.js -->
<h2 id="player-name" class="fighter-name">
<i class="fas fa-hat-wizard icon-player"></i> Елена
</h2>
</div>
<div class="panel-content">
<div class="stat-bar-container health">
<div class="bar-icon"><i class="fas fa-heart"></i></div>
<div class="bar-wrapper">
<div class="bar health-bar" id="player-hp-bar">
<div id="player-hp-fill" class="bar-fill" style="width: 100%;"></div>
<span id="player-hp-text" class="bar-text">120 / 120</span>
</div>
</div>
</div>
<!-- Тип ресурса (mana/stamina/dark-energy) и иконка будут обновляться из ui.js -->
<div class="stat-bar-container resource mana">
<div class="bar-icon"><i class="fas fa-flask"></i></div>
<div class="bar-wrapper">
<div class="bar resource-bar" id="player-resource-bar">
<div id="player-resource-fill" class="bar-fill" style="width: 100%;"></div>
<span id="player-resource-text" class="bar-text">150 / 150</span>
</div>
</div>
</div>
<div class="status-area" id="player-status-area">
<i class="fas fa-shield-alt icon-status"></i> <strong>Статус:</strong> <span id="player-status">Готов(а)</span>
</div>
<div class="effects-area" id="player-effects">
<div class="effect-category">
<i class="fas fa-shield-alt icon-effects-buff"></i>
<strong>Усиления:</strong>
<span class="effect-list player-buffs">Нет</span>
</div>
<div class="effect-category">
<i class="fas fa-skull-crossbones icon-effects-debuff"></i>
<strong>Ослабления:</strong>
<span class="effect-list player-debuffs">Нет</span>
</div>
</div>
</div>
</section>
<section id="controls-panel" class="controls-panel-new">
<!-- Индикатор хода будет обновляться из ui.js -->
<h3 id="turn-indicator">Ход: Игрок 1</h3>
<div class="controls-layout">
<div class="control-group basic-actions">
<button id="button-attack" class="action-button basic" data-action="BASIC_ATTACK" title="Базовая атака"><i class="fas fa-shoe-prints"></i> Атака</button>
<button id="button-block" class="action-button basic" data-action="BLOCK" title="Встать в защиту (Завершает ход!)" disabled><i class="fas fa-shield-alt"></i> Защита</button>
</div>
<div class="control-group ability-list">
<h4><i class="fas fa-book-sparkles"></i> Способности</h4>
<!-- Способности будут загружены из client.js -->
<div id="abilities-grid" class="abilities-grid">
<p class="placeholder-text">Загрузка способностей...</p>
</div>
</div>
</div>
</section>
</div> <!-- Конец player-column -->
<!-- Колонка Противника (Панель 2 в UI) -->
<div class="opponent-column">
<section id="opponent-panel" class="fighter-panel">
<div class="panel-header">
<div class="character-visual">
<!-- Аватар будет обновляться из ui.js -->
<img src="images/balard_avatar.jpg" alt="Аватар игрока 2" class="avatar-image opponent-avatar">
</div>
<!-- Имя будет обновляться из ui.js -->
<h2 id="opponent-name" class="fighter-name">
<i class="fas fa-khanda icon-opponent"></i> Балард
</h2>
</div>
<div class="panel-content">
<div class="stat-bar-container health">
<div class="bar-icon"><i class="fas fa-heart"></i></div>
<div class="bar-wrapper">
<div class="bar health-bar" id="opponent-hp-bar">
<div id="opponent-hp-fill" class="bar-fill" style="width: 100%;"></div>
<span id="opponent-hp-text" class="bar-text">140 / 140</span>
</div>
</div>
</div>
<!-- Тип ресурса и иконка будут обновляться из ui.js -->
<div class="stat-bar-container resource stamina">
<div class="bar-icon"><i class="fas fa-fire-alt"></i></div>
<div class="bar-wrapper">
<div class="bar resource-bar" id="opponent-resource-bar">
<div id="opponent-resource-fill" class="bar-fill" style="width: 100%;"></div>
<span id="opponent-resource-text" class="bar-text">100 / 100</span>
</div>
</div>
</div>
<div class="status-area" id="opponent-status-area">
<i class="fas fa-shield-alt icon-status"></i> <strong>Статус:</strong> <span id="opponent-status">Готов(а)</span>
</div>
<div class="effects-area" id="opponent-effects">
<div class="effect-category">
<i class="fas fa-shield-alt icon-effects-buff"></i>
<strong>Усиления:</strong>
<span class="effect-list opponent-buffs">Нет</span>
</div>
<div class="effect-category">
<i class="fas fa-skull-crossbones icon-effects-debuff"></i>
<strong>Ослабления:</strong>
<span class="effect-list opponent-debuffs">Нет</span>
</div>
</div>
</div>
</section>
<section id="log-panel" class="battle-log-new">
<h3><i class="fas fa-scroll"></i> Лог Боя</h3>
<ul id="log-list">
<li class="log-system">Ожидание подключения к серверу...</li>
</ul>
</section>
</div> <!-- Конец opponent-column -->
</main> <!-- Конец .battle-arena-container -->
<!-- Модальное окно конца игры -->
<div id="game-over-screen" class="modal hidden">
<div class="modal-content">
<h2 id="result-message">Победа!</h2>
<button id="restart-game-button"><i class="fas fa-redo"></i> Новая Игра / Готов к рестарту</button>
</div>
</div>
</div> <!-- Конец .game-wrapper -->
<script src="/socket.io/socket.io.js"></script>
<script src="./js/ui.js"></script> <!-- ui.js должен быть до client.js -->
<script src="./js/client.js"></script>
</body>
</html>