Complete local voxel MVP with server, client, MCP, packages and world interchange
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<meta name="color-scheme" content="dark" />
|
||||
<title>Shacraft · Мир</title>
|
||||
<link
|
||||
rel="icon"
|
||||
href="data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 32 32%27%3E%3Cpath fill=%27%2394ae81%27 d=%27M16 1 30 9v15L16 32 2 24V9z%27/%3E%3C/svg%3E"
|
||||
/>
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<canvas
|
||||
id="world-canvas"
|
||||
aria-label="Трёхмерный мир Shacraft. WASD — движение, пробел — прыжок, мышь — обзор."
|
||||
></canvas>
|
||||
<div id="labels" aria-hidden="true"></div>
|
||||
<header class="topbar">
|
||||
<div class="identity">
|
||||
<svg viewBox="0 0 28 32" width="27" height="30" aria-hidden="true">
|
||||
<path d="M14 1 27 8.5 14 16 1 8.5Z" fill="#c0d3a9" />
|
||||
<path d="M1 8.5 14 16v15L1 23.5Z" fill="#6d8560" />
|
||||
<path d="m14 16 13-7.5v15L14 31Z" fill="#94ae81" />
|
||||
</svg>
|
||||
<div>
|
||||
<strong>Shacraft</strong
|
||||
><button id="world-button" class="world-name" title="Выбрать мир">
|
||||
Подключение… ▾
|
||||
</button>
|
||||
</div>
|
||||
<span id="connection" role="status">Загрузка</span>
|
||||
</div>
|
||||
<nav aria-label="Игровое меню">
|
||||
<button id="library-button">Блоки <kbd>E</kbd></button
|
||||
><button id="diagnostics-button" title="Открыть диагностику">
|
||||
Диагностика <kbd>F3</kbd></button
|
||||
><button id="menu-button" aria-label="Меню игры">☰</button>
|
||||
</nav>
|
||||
</header>
|
||||
<div id="crosshair" aria-hidden="true"></div>
|
||||
<div id="target-label"></div>
|
||||
<div id="match" hidden></div>
|
||||
<div id="toast" role="status" hidden></div>
|
||||
<div class="bottom-left">
|
||||
<div id="chat-log" aria-live="polite"></div>
|
||||
<form id="chat-form" hidden>
|
||||
<input
|
||||
id="chat-input"
|
||||
autocomplete="off"
|
||||
maxlength="240"
|
||||
aria-label="Сообщение в чат"
|
||||
placeholder="Сообщение · Enter — отправить, Esc — закрыть"
|
||||
/>
|
||||
</form>
|
||||
<div id="hints">
|
||||
<span><kbd>W A S D</kbd> движение</span
|
||||
><span><kbd>Пробел</kbd> прыжок</span
|
||||
><span><kbd>ЛКМ / ПКМ</kbd> убрать / поставить</span
|
||||
><span><kbd>T</kbd> чат</span>
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<div id="selected-name"></div>
|
||||
<div id="hotbar" role="toolbar" aria-label="Быстрый выбор блоков"></div>
|
||||
<div id="play-hint">
|
||||
Нажмите на мир для управления · без захвата мыши: удерживайте и двигайте
|
||||
</div>
|
||||
</footer>
|
||||
<div id="fatal" hidden role="alert"></div>
|
||||
<aside id="menu" class="panel" hidden aria-label="Меню игры">
|
||||
<div class="panel-head">
|
||||
<h1>Меню игры</h1>
|
||||
<button data-close="menu" aria-label="Закрыть меню">×</button>
|
||||
</div>
|
||||
<label for="player-name">Имя игрока</label>
|
||||
<div class="inline">
|
||||
<input id="player-name" maxlength="24" autocomplete="off" /><button
|
||||
id="rename-button"
|
||||
>
|
||||
Применить
|
||||
</button>
|
||||
</div>
|
||||
<button id="resume-button" class="primary wide">Вернуться в мир</button
|
||||
><button id="respawn-button" class="wide">
|
||||
Вернуться к точке появления</button
|
||||
><button id="spleef-button" class="wide">Начать Spleef</button>
|
||||
<p class="muted">
|
||||
В Spleef убирайте снег под соперником. Последний игрок на арене
|
||||
побеждает.
|
||||
</p>
|
||||
<div class="rule"></div>
|
||||
<label for="sensitivity">Чувствительность мыши</label
|
||||
><input
|
||||
type="range"
|
||||
id="sensitivity"
|
||||
min="0.0008"
|
||||
max="0.006"
|
||||
step="0.0002"
|
||||
value="0.0024"
|
||||
/>
|
||||
<p class="muted">
|
||||
Esc освобождает мышь. Перетаскивание работает и без захвата. Средняя
|
||||
кнопка выбирает блок под прицелом.
|
||||
</p>
|
||||
<button id="reconnect-button" class="wide">Переподключиться</button>
|
||||
</aside>
|
||||
<aside id="worlds" class="panel" hidden aria-label="Выбор мира">
|
||||
<div class="panel-head">
|
||||
<h1>Миры</h1>
|
||||
<button data-close="worlds" aria-label="Закрыть миры">×</button>
|
||||
</div>
|
||||
<p class="muted">Изменения каждого экземпляра сохраняются независимо.</p>
|
||||
<div id="world-list"></div>
|
||||
</aside>
|
||||
<aside
|
||||
id="library"
|
||||
class="panel library"
|
||||
hidden
|
||||
aria-label="Каталог блоков"
|
||||
>
|
||||
<div class="panel-head">
|
||||
<div>
|
||||
<h1>Библиотека блоков</h1>
|
||||
<p id="catalog-count" class="muted">Каталог сервера</p>
|
||||
</div>
|
||||
<button data-close="library" aria-label="Закрыть библиотеку">×</button>
|
||||
</div>
|
||||
<input
|
||||
id="catalog-search"
|
||||
type="search"
|
||||
placeholder="Поиск: oak, stairs, glass…"
|
||||
aria-label="Поиск по каталогу"
|
||||
/>
|
||||
<p class="muted">
|
||||
Выберите блок для текущей ячейки. Свойства состояний показаны под
|
||||
названием.
|
||||
</p>
|
||||
<div id="catalog-list"></div>
|
||||
<button id="catalog-more" class="wide">Показать ещё</button>
|
||||
</aside>
|
||||
<aside
|
||||
id="diagnostics"
|
||||
class="panel diagnostics"
|
||||
hidden
|
||||
aria-label="Диагностика"
|
||||
>
|
||||
<div class="panel-head">
|
||||
<h1>Диагностика</h1>
|
||||
<button data-close="diagnostics" aria-label="Закрыть диагностику">
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
<dl id="debug-values"></dl>
|
||||
<div id="package-status" class="muted">Пакеты ещё не загружены</div>
|
||||
<button id="resync-button" class="wide">Сверить снимок мира</button>
|
||||
<p class="muted">
|
||||
Сервер подтверждает движение и правки. RAM процесса и полезные данные
|
||||
кэша — разные измерения.
|
||||
</p>
|
||||
</aside>
|
||||
<script type="module" src="/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user