diff --git a/apps/game/src/scenes/InventoryScene.ts b/apps/game/src/scenes/InventoryScene.ts index b17caff..c413ba3 100644 --- a/apps/game/src/scenes/InventoryScene.ts +++ b/apps/game/src/scenes/InventoryScene.ts @@ -22,12 +22,12 @@ } protected build(): void { - const panel = new Panel({ width: 280, height: 180 }); - panel.position.set((Game.VIRTUAL_W - 280) / 2, (Game.VIRTUAL_H - 180) / 2); + const panel = new Panel({ width: 280, height: 196 }); + panel.position.set((Game.VIRTUAL_W - 280) / 2, (Game.VIRTUAL_H - 196) / 2); const title = new PixelText({ text: 'ЗВОНАРЬ', size: 14, color: 0xd8c79a }); title.anchor.set(0.5); - title.position.set(140, 16); + title.position.set(140, 14); panel.addChild(title); const addLine = (text: string, color: number, x: number, y: number): void => { @@ -36,15 +36,17 @@ panel.addChild(t); }; - // Сумка: список с курсором, Enter — применить выбранный предмет. - addLine('Сумка', 0x999988, 16, 36); - const slots = this.game.inventory.all; - const result = new PixelText({ text: '', size: 10, color: 0xf2d49a }); - result.position.set(20, 150); + // Статус-строка: подсказка до первого применения, результат — после. + const result = new PixelText({ text: 'Enter — применить, Esc — назад', size: 9, color: 0xf2d49a }); + result.position.set(16, 28); panel.addChild(result); + + // Сумка: список с курсором и скроллом (6 строк), Enter — применить. + addLine('Сумка', 0x999988, 16, 40); + const slots = this.game.inventory.all; if (slots.length > 0) { - this.menu = new MenuList({ width: 240, height: 14, gap: 1, size: 10 }); - this.menu.position.set(20, 48); + this.menu = new MenuList({ width: 240, height: 14, gap: 1, size: 10, visibleRows: 6 }); + this.menu.position.set(20, 52); this.menu.setItems( slots.map((slot) => ({ label: slot.count > 1 ? `${itemName(slot.id)} ×${slot.count}` : itemName(slot.id), @@ -53,24 +55,18 @@ ); panel.addChild(this.menu); } else { - addLine('— пусто —', 0x777788, 24, 50); + addLine('— пусто —', 0x777788, 24, 54); } - // Журнал квестов — ниже сумки, без фокуса. - const menuBottom = 48 + Math.max(slots.length, 1) * 15; - addLine('Журнал', 0x999988, 16, menuBottom + 2); - let y = menuBottom + 17; + // Журнал квестов — фиксированно ниже сумки, без фокуса. + addLine('Журнал', 0x999988, 16, 144); + let y = 158; for (const entry of questLog(this.game.state)) { const mark = entry.done ? 'x' : '·'; addLine(`[${mark}] ${entry.text}`, entry.done ? 0xd8c79a : 0xaaaaaa, 24, y); - y += 13; + y += 12; } - const hint = new PixelText({ text: 'Enter — применить, Esc — назад', size: 9, color: 0x777788 }); - hint.anchor.set(0.5); - hint.position.set(140, 168); - panel.addChild(hint); - this.view.addChild(panel); this.game.renderer.uiRoot.addChild(this.view); } diff --git a/apps/game/src/scenes/SettingsScene.ts b/apps/game/src/scenes/SettingsScene.ts index 4d5e6f0..e6cc3fe 100644 --- a/apps/game/src/scenes/SettingsScene.ts +++ b/apps/game/src/scenes/SettingsScene.ts @@ -50,19 +50,19 @@ this.back(); } + /** Список собирается один раз; громкости обновляются value-слотом. */ private rebuild(): void { - const s = this.game.settings.data; this.menu!.setItems([ - { label: this.volumeLabel('Общая', s.master), onSelect: () => this.adjust(0, 0.1) }, - { label: this.volumeLabel('Амбиент', s.ambience), onSelect: () => this.adjust(1, 0.1) }, - { label: this.volumeLabel('Звуки', s.sfx), onSelect: () => this.adjust(2, 0.1) }, + { label: 'Общая', value: this.volumeBars(this.game.settings.data.master), onSelect: () => this.adjust(0, 0.1) }, + { label: 'Амбиент', value: this.volumeBars(this.game.settings.data.ambience), onSelect: () => this.adjust(1, 0.1) }, + { label: 'Звуки', value: this.volumeBars(this.game.settings.data.sfx), onSelect: () => this.adjust(2, 0.1) }, { label: 'Назад', onSelect: () => this.back() } ]); } - private volumeLabel(name: string, v: number): string { + private volumeBars(v: number): string { const bars = Math.round(v * 10); - return `${name} ${'▮'.repeat(bars)}${'▯'.repeat(10 - bars)}`; + return `${'▮'.repeat(bars)}${'▯'.repeat(10 - bars)}`; } private adjust(index: number, delta: number): void { @@ -75,7 +75,7 @@ const value = Math.round(Math.min(1, Math.max(0, s[key] + delta)) * 10) / 10; this.game.settings.update({ [key]: value }); if (delta > 0) playSfx(this.game.audio, 'sfx/ui_click'); - this.rebuild(); + this.menu!.setValue(index, this.volumeBars(value)); } private back(): void {