85 lines
3.2 KiB
TypeScript
85 lines
3.2 KiB
TypeScript
import { getRenderSettings, setRenderSettings } from '../pixi/renderSettings';
|
|
|
|
/** Builds a toggle button that shows its current on/off state in its own label and flips it on
|
|
* click — the DOM-side equivalent of a checkbox, styled like the rest of the menu's buttons. */
|
|
function createToggle(label: string, initial: boolean, onChange: (value: boolean) => void): HTMLButtonElement {
|
|
const btn = document.createElement('button');
|
|
btn.type = 'button';
|
|
btn.className = 'menu-btn';
|
|
let value = initial;
|
|
|
|
function render(): void {
|
|
btn.textContent = `${label}: ${value ? 'вкл' : 'выкл'}`;
|
|
}
|
|
render();
|
|
|
|
btn.addEventListener('click', () => {
|
|
value = !value;
|
|
render();
|
|
onChange(value);
|
|
});
|
|
|
|
return btn;
|
|
}
|
|
|
|
/** Builds the settings screen — rendering-diagnostics toggles that take effect the next time a
|
|
* game is (re)started (GameCanvas reads them once, on mount), plus a seed field, reachable from
|
|
* the main menu.
|
|
* @param currentSeed The running game's current PRNG seed (see GameStore.seed) — 0 if no game has
|
|
* started yet this page load. Shown as the seed field's starting value.
|
|
* @param onStartWithSeed Called with a new seed the instant the seed field's value is committed
|
|
* (blur or Enter) — starts (or restarts) a game seeded from it, discarding any existing save, the
|
|
* same way "Новая игра" does. */
|
|
export function createSettingsScreen(currentSeed: number, onBack: () => void, onStartWithSeed: (seed: number) => void): HTMLElement {
|
|
const root = document.createElement('div');
|
|
root.className = 'main-menu';
|
|
|
|
const title = document.createElement('h1');
|
|
title.className = 'main-menu__title';
|
|
title.textContent = 'Настройки';
|
|
|
|
const buttons = document.createElement('div');
|
|
buttons.className = 'main-menu__buttons';
|
|
|
|
const settings = getRenderSettings();
|
|
|
|
const antialiasingBtn = createToggle('Антиалиасинг экрана', settings.antialiasing, (value) => {
|
|
setRenderSettings({ antialiasing: value });
|
|
});
|
|
|
|
const noScaleBtn = createToggle('Рендер без масштабирования (k=1)', settings.noScale, (value) => {
|
|
setRenderSettings({ noScale: value });
|
|
});
|
|
|
|
const seedLabel = document.createElement('label');
|
|
seedLabel.className = 'settings-seed-label';
|
|
seedLabel.textContent = 'Сид игры (новая игра при изменении)';
|
|
|
|
const seedInput = document.createElement('input');
|
|
seedInput.type = 'number';
|
|
seedInput.className = 'settings-seed-input';
|
|
seedInput.min = '0';
|
|
seedInput.max = '4294967295';
|
|
seedInput.step = '1';
|
|
seedInput.value = String(currentSeed);
|
|
seedInput.addEventListener('change', () => {
|
|
const parsed = Math.floor(Number(seedInput.value));
|
|
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
seedInput.value = String(currentSeed);
|
|
return;
|
|
}
|
|
onStartWithSeed(parsed >>> 0);
|
|
});
|
|
seedLabel.appendChild(seedInput);
|
|
|
|
const backBtn = document.createElement('button');
|
|
backBtn.type = 'button';
|
|
backBtn.className = 'menu-btn';
|
|
backBtn.textContent = 'Назад';
|
|
backBtn.addEventListener('click', onBack);
|
|
|
|
buttons.append(antialiasingBtn, noScaleBtn, seedLabel, backBtn);
|
|
root.append(title, buttons);
|
|
return root;
|
|
}
|