refactor: рабочая база на three.js + меню/правила уровней + доки
Полный рефакторинг проекта в стабильную расширяемую базу рогалика. Почему: после разнесения single-file на модули потерялся вызов генерации карты (RoomMap не генерировал комнаты) → игра падала на старте; баг скрывался тем, что Bun-бандлер не проверяет типы. Архитектура: - Логика игры (src/core/) полностью отделена от рендера: без three.js и DOM, тестируется без браузера. - Рендер мира на three.js с ортокамерой (2D-вид); HUD/миникарта — 2D-канвас поверх. - Фиксированный игровой цикл 60 Гц + интерполяция (раньше скорость зависела от частоты кадров). - Seeded-RNG, ввод через абстрактные «намерения» (InputState). Возможности: - Стартовое меню с выбором уровня (Esc → меню). - Конфигуратор уровней: LevelRules + 5 пресетов (размер карты, плотность/сила врагов, HP, фиксированный seed). - Тема внешнего вида (render/theme.ts) — задел под кастомные ассеты. Качество: - 27 юнит-тестов ядра (генерация, симметрия дверей, коллизии, спавн, правила). - Два круга adversarial-ревью; исправлено 6 реальных багов (кнокбэк сквозь стены → софт-лок; незакрываемая сокровищница; фикс-сид после рестарта; перенос ввода между забегами; нет source maps; неточности в доках). - Документация: README, docs/ARCHITECTURE.md, CLAUDE.md, docs/HOWTO.md. - dist/ исключён из гита; bun.lock зафиксирован. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
import { T_WALL, T_FLOOR, T_DOOR, COLS, ROWS, DOOR } from '../../config';
|
||||
import type { Doors } from '../types';
|
||||
|
||||
/**
|
||||
* Строит свежую сетку тайлов комнаты: по краям стены, внутри пол.
|
||||
* Если передан doorState — в стенах прорезаются дверные проёмы.
|
||||
*/
|
||||
export function buildTiles(doorState?: Doors): number[][] {
|
||||
const tiles: number[][] = [];
|
||||
for (let r = 0; r < ROWS; r++) {
|
||||
tiles[r] = [];
|
||||
for (let c = 0; c < COLS; c++) {
|
||||
const isEdge = r === 0 || r === ROWS - 1 || c === 0 || c === COLS - 1;
|
||||
tiles[r][c] = isEdge ? T_WALL : T_FLOOR;
|
||||
}
|
||||
}
|
||||
if (doorState) placeDoors(tiles, doorState);
|
||||
return tiles;
|
||||
}
|
||||
|
||||
/** Помечает дверные тайлы на готовой сетке согласно набору открытых дверей. */
|
||||
export function placeDoors(tiles: number[][], doors: Doors): void {
|
||||
if (doors.up) for (const c of DOOR.up.cols) tiles[DOOR.up.row][c] = T_DOOR;
|
||||
if (doors.down) for (const c of DOOR.down.cols) tiles[DOOR.down.row][c] = T_DOOR;
|
||||
if (doors.left) for (const r of DOOR.left.rows) tiles[r][DOOR.left.col] = T_DOOR;
|
||||
if (doors.right) for (const r of DOOR.right.rows) tiles[r][DOOR.right.col] = T_DOOR;
|
||||
}
|
||||
Reference in New Issue
Block a user