feat: improve battle notice system with expanded content, centralized constants, and fixed text wrapping

This commit is contained in:
Horoli 2026-05-24 22:32:48 +09:00
parent 1668e3c941
commit ddccd01eb6
5 changed files with 41 additions and 18 deletions

View File

@ -164,6 +164,10 @@ export const UI = {
SELECTED_FIGHTER_OUTLINE_GREEN: 228,
SELECTED_FIGHTER_OUTLINE_BLUE: 64,
SELECTED_FIGHTER_OUTLINE_ALPHA: 0.65,
// 상단 종족별 사망 통계 공지 설정
BATTLE_NOTICE_DELAY_MS: 5000,
BATTLE_NOTICE_VISIBLE_MS: 2000,
BATTLE_NOTICE_INTERVAL_MS: 10000,
};
// 9. TEAM 도메인

View File

@ -51,9 +51,6 @@ import {
import { updateScoreboard } from "../../ui/arenaScoreboard.js";
import { appendKillLog, resetKillLog } from "../../ui/arenaKillLog.js";
import {
BATTLE_NOTICE_DELAY_MS,
BATTLE_NOTICE_INTERVAL_MS,
BATTLE_NOTICE_VISIBLE_MS,
clearBattleNotice,
showBattleDeathNotice,
} from "../../ui/battleDeathNotice.js";
@ -295,7 +292,7 @@ export class ArenaScene extends Phaser.Scene {
});
}
scheduleBattleNotice(delayMs = BATTLE_NOTICE_DELAY_MS) {
scheduleBattleNotice(delayMs = UI.BATTLE_NOTICE_DELAY_MS) {
this.battleNoticeTimer?.remove(false);
this.battleNoticeTimer = this.time.delayedCall(delayMs, () => {
this.battleNoticeTimer = null;
@ -339,12 +336,12 @@ export class ArenaScene extends Phaser.Scene {
showBattleDeathNotice(noticeNode, message);
this.battleNoticeHideTimer?.remove(false);
this.battleNoticeHideTimer = this.time.delayedCall(BATTLE_NOTICE_VISIBLE_MS, () => {
this.battleNoticeHideTimer = this.time.delayedCall(UI.BATTLE_NOTICE_VISIBLE_MS, () => {
this.battleNoticeHideTimer = null;
clearBattleNotice(noticeNode);
if (!this.matchOver && !this.presentationMode) {
this.scheduleBattleNotice(BATTLE_NOTICE_INTERVAL_MS);
this.scheduleBattleNotice(UI.BATTLE_NOTICE_INTERVAL_MS);
}
});
}

View File

@ -124,11 +124,12 @@
display: flex;
align-items: center;
justify-content: center;
width: min(420px, 72vmin, calc(100vw - 64px));
width: auto;
max-width: min(640px, calc(100vw - 40px));
min-height: 38px;
border: 1px solid rgb(238 185 73 / 0.26);
border-radius: 8px;
padding: 8px 14px;
padding: 8px 18px;
background: rgb(8 10 7 / 0.68);
color: #ffe8b4;
font-size: 0.8rem;
@ -136,6 +137,7 @@
line-height: 1.35;
text-align: center;
text-shadow: 1px 1px 2px #000;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transform: translate(-50%, -10px);

View File

@ -1,3 +1,5 @@
import { UI } from "../constants.js";
const SPECIES_KEYS = ["human", "orc", "skeleton", "slime", "wolf", "bear"];
const SPECIES_LABELS = {
bear: "곰",
@ -22,9 +24,12 @@ const DEATH_NOTICE_TEMPLATES = [
"{species}{particle} 전투 중 {count}명 쓰러졌습니다. 관중석은 침착한 척하는 중입니다.",
];
export const BATTLE_NOTICE_DELAY_MS = 5000;
export const BATTLE_NOTICE_VISIBLE_MS = 2000;
export const BATTLE_NOTICE_INTERVAL_MS = 10000;
const SYSTEM_TIP_TEMPLATES = [
"경보: 화염 메테오는 낙하 지점 5x5 영역에 강력한 폭발 피해를 입힙니다!",
"주의: 냉기 메테오는 피해와 함께 2초간 동결 및 냉각을 유발합니다.",
"팁: 근접 캐릭터는 20% 확률로 치명타를 터뜨려 적을 즉사시킵니다.",
"성장: 적 처치 시 체력을 30% 회복하며, 크기와 속도가 최대 5배까지 커집니다.",
];
export function createDeathCounts() {
return SPECIES_KEYS.reduce((counts, species) => {
@ -42,7 +47,8 @@ export function normalizeDeathCounts(value = {}) {
export function addDeathCounts(baseCounts, matchCounts) {
return SPECIES_KEYS.reduce((counts, species) => {
counts[species] = (baseCounts?.[species] ?? 0) + (matchCounts?.[species] ?? 0);
counts[species] =
(baseCounts?.[species] ?? 0) + (matchCounts?.[species] ?? 0);
return counts;
}, {});
}
@ -52,17 +58,26 @@ export function normalizeSpecies(value) {
}
export function createDeathNoticeMessage(deathsBySpecies, seed = 0) {
const topSpecies = SPECIES_KEYS
.map((species) => ({ species, count: deathsBySpecies?.[species] ?? 0 }))
.sort((left, right) => right.count - left.count)[0];
// 3번에 한 번꼴로 시스템 팁 출력
if (seed % 3 === 0) {
return SYSTEM_TIP_TEMPLATES[
Math.floor(seed / 3) % SYSTEM_TIP_TEMPLATES.length
];
}
const topSpecies = SPECIES_KEYS.map((species) => ({
species,
count: deathsBySpecies?.[species] ?? 0,
})).sort((left, right) => right.count - left.count)[0];
if (!topSpecies || topSpecies.count === 0) {
return "오늘 사망자 집계는 아직 0명입니다. 이 평화가 얼마나 버틸까요?";
}
const template = DEATH_NOTICE_TEMPLATES[
(topSpecies.count + seed) % DEATH_NOTICE_TEMPLATES.length
];
const template =
DEATH_NOTICE_TEMPLATES[
(topSpecies.count + seed) % DEATH_NOTICE_TEMPLATES.length
];
return template
.replace("{species}", SPECIES_LABELS[topSpecies.species])

View File

@ -260,4 +260,9 @@
- 새로운 CSS 모듈 구조와 디자인 원칙을 설명하는 `context/style.md` 문서를 신규 생성.
- `agent.md`의 상세 기술 가이드(Context Routing) 섹션에 스타일 및 디자인 항목을 추가하여 문서 접근성 개선.
42. 상단 공지(Battle Notice) 콘텐츠 확장 (완료)
- **조치 사항**:
- 사망 통계만 보여주던 공지 UI에 게임 시스템 가이드(화염/냉기 메테오 특성, 밀리 치명타 확률 등) 팁을 추가.
- 사망 통계 공지 2회당 1회의 비율로 시스템 팁이 교차 출력되도록 로직 개선.