feat: add stable story atmosphere and motion controls

This commit is contained in:
2026-07-22 02:01:19 +09:00
parent fa26992b56
commit 9d767e864c
8 changed files with 1160 additions and 23 deletions

View File

@@ -13,6 +13,12 @@ import {
saveAudioPreferences,
updateAudioPreference
} from '../settings/audioPreferences';
import {
loadVisualMotionMode,
nextVisualMotionMode,
saveVisualMotionMode,
visualMotionModeLabel
} from '../settings/visualMotion';
import { battleIdForCampaignStep, isCampCampaignStep } from '../state/campaignRouting';
import { readCampaignBattleResume, type CampaignBattleResume } from '../state/battleSaveStorage';
import {
@@ -454,11 +460,11 @@ export class TitleScene extends Phaser.Scene {
this.closeSaveSlotPanel();
const panel = this.add.container(x, y + ui(126));
const backdrop = this.add.rectangle(0, 0, ui(320), ui(420), 0x0b1118, 1);
const backdrop = this.add.rectangle(0, 0, ui(320), ui(468), 0x0b1118, 1);
backdrop.setStrokeStyle(ui(1), palette.gold, 0.52);
backdrop.setInteractive();
const title = this.add.text(0, -ui(150), '설정', {
const title = this.add.text(0, -ui(174), '설정', {
fontSize: uiPx(24),
color: '#f1e3c2',
fontStyle: '700',
@@ -467,7 +473,7 @@ export class TitleScene extends Phaser.Scene {
});
title.setOrigin(0.5);
const soundText = this.createSettingsButton(0, -ui(102), this.soundLabel());
const soundText = this.createSettingsButton(0, -ui(126), this.soundLabel());
soundText.on('pointerdown', () => {
const preferences = loadAudioPreferences();
const muted = !soundDirector.isMuted();
@@ -477,16 +483,16 @@ export class TitleScene extends Phaser.Scene {
soundDirector.playSelect();
});
const musicText = this.createSettingsButton(0, -ui(60), this.audioCategoryLabel('music'));
const musicText = this.createSettingsButton(0, -ui(84), this.audioCategoryLabel('music'));
musicText.on('pointerdown', () => this.cycleAudioLevel('music', musicText));
const effectsText = this.createSettingsButton(0, -ui(18), this.audioCategoryLabel('effects'));
const effectsText = this.createSettingsButton(0, -ui(42), this.audioCategoryLabel('effects'));
effectsText.on('pointerdown', () => this.cycleAudioLevel('effects', effectsText));
const ambienceText = this.createSettingsButton(0, ui(24), this.audioCategoryLabel('ambience'));
const ambienceText = this.createSettingsButton(0, 0, this.audioCategoryLabel('ambience'));
ambienceText.on('pointerdown', () => this.cycleAudioLevel('ambience', ambienceText));
const presentationText = this.createSettingsButton(0, ui(66), this.combatPresentationLabel());
const presentationText = this.createSettingsButton(0, ui(42), this.combatPresentationLabel());
presentationText.on('pointerdown', () => {
const nextMode = nextCombatPresentationMode(loadCombatPresentationMode());
saveCombatPresentationMode(nextMode);
@@ -494,13 +500,21 @@ export class TitleScene extends Phaser.Scene {
soundDirector.playSelect();
});
const close = this.createSettingsButton(0, ui(110), '닫기');
const motionText = this.createSettingsButton(0, ui(84), this.visualMotionLabel());
motionText.on('pointerdown', () => {
const nextMode = nextVisualMotionMode(loadVisualMotionMode());
saveVisualMotionMode(nextMode);
motionText.setText(this.visualMotionLabel());
soundDirector.playSelect();
});
const close = this.createSettingsButton(0, ui(132), '닫기');
close.on('pointerdown', () => {
soundDirector.playSelect();
this.closeSettingsPanel();
});
const hint = this.add.text(0, ui(150), '항목을 눌러 단계 변경 · Esc 닫기', {
const hint = this.add.text(0, ui(178), '항목을 눌러 단계 변경 · Esc 닫기', {
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
fontSize: uiPx(11),
color: '#9fb0bf',
@@ -510,7 +524,7 @@ export class TitleScene extends Phaser.Scene {
});
hint.setOrigin(0.5);
panel.add([backdrop, title, soundText, musicText, effectsText, ambienceText, presentationText, close, hint]);
panel.add([backdrop, title, soundText, musicText, effectsText, ambienceText, presentationText, motionText, close, hint]);
panel.setAlpha(0);
this.settingsPanel = panel;
this.tweens.add({ targets: panel, alpha: 1, y: y + ui(116), duration: 160, ease: 'Sine.easeOut' });
@@ -559,6 +573,10 @@ export class TitleScene extends Phaser.Scene {
return `전투 연출: ${combatPresentationModeLabel(loadCombatPresentationMode())}`;
}
private visualMotionLabel() {
return `화면 움직임: ${visualMotionModeLabel(loadVisualMotionMode())}`;
}
private closeSettingsPanel() {
this.settingsPanel?.destroy();
this.settingsPanel = undefined;