대화창 (다이얼로그 박스)

Dialogue Box

초상화·타이프라이터 텍스트·다음으로 넘어가라는 표시가 한 세트로 묶여 NPC 대사를 순차적으로 보여주는 UI.

다른 이름: 대화 상자Dialogue windowNPC 대화창
···
html
<div class="dbwrap"><div class="dbportrait" id="portrait"></div>
<div class="dbbox"><div class="dbname" id="name">GUIDE</div><div class="dbtext" id="text"></div><div class="dbnext" id="next">▾</div></div></div>
css
.dbwrap{position:relative;width:min(94%,420px);display:flex;gap:clamp(8px,3vmin,14px);align-items:flex-end}
.dbportrait{width:clamp(30px,13vmin,52px);height:clamp(30px,13vmin,52px);border-radius:9px;background:var(--accent);flex:none;transition:background .3s}
.dbbox{position:relative;flex:1;background:var(--surface);border:1px solid var(--line);border-radius:10px;padding:clamp(8px,3vmin,14px);min-height:clamp(48px,18vmin,74px)}
.dbname{font:800 clamp(9px,2.6vmin,11px) monospace;color:var(--accent);letter-spacing:.08em;margin-bottom:4px}
.dbtext{font:clamp(10px,3.2vmin,13px)/1.5 inherit;color:var(--fg);min-height:2.6em}
.dbnext{position:absolute;right:10px;bottom:6px;color:var(--muted);font-size:12px;opacity:0;animation:dbblink 1s steps(2) infinite}
.dbnext.show{opacity:1}
@keyframes dbblink{50%{opacity:.15}}
js
const text=document.getElementById('text');
const next=document.getElementById('next');
const name=document.getElementById('name');
const portrait=document.getElementById('portrait');
const lines=[
  ['GUIDE','var(--accent)','이 문을 지나면 더 이상 돌아갈 수 없어.'],
  ['GUIDE','var(--accent)','준비가 되었다면 문을 열겠다.'],
  ['STRANGER','var(--accent-2)','...그대, 정말 가려는 건가?'],
];
let li=0;
function typeLine(){
  const [n,color,str]=lines[li];
  name.textContent=n;
  portrait.style.background=color;
  text.textContent='';
  next.classList.remove('show');
  let ci=0;
  const timer=setInterval(function(){
    text.textContent=str.slice(0,ci+1);
    ci++;
    if(ci>=str.length){
      clearInterval(timer);
      next.classList.add('show');
      setTimeout(function(){
        li=(li+1)%lines.length;
        typeLine();
      }, 1300);
    }
  }, 32);
}
typeLine();

대화창은 세 요소로 이뤄진다 — 말하는 사람을 알려주는 초상화(portrait), 글자가 한 글자씩 나타나는 타이프라이터 텍스트, 그리고 문장이 다 나온 뒤 "다음으로 넘어가도 된다"를 알리는 깜빡이는 표시(대개 아래쪽 삼각형이나 화살표). 이 세 개가 각자 다른 질문에 답한다 — 누가, 무슨 말을, 언제 넘어갈 수 있는가.

타이프라이터 효과는 단순히 예뻐서가 아니라 읽는 속도를 게임이 통제하기 위한 장치다. 너무 빠르면 급하게 느껴지고 너무 느리면 지루하다 — 보통 한 글자당 20~40ms가 무난한 범위다. 입력이 들어오면(클릭·버튼) 즉시 전체 텍스트를 다 보여주고 넘어가게 하는 스킵 기능은 필수에 가깝다 — 이미 읽은 대사를 다시 천천히 보는 건 누구도 원하지 않는다.

초상화는 감정에 따라 바뀌는 여러 장을 준비해두면 대사의 톤을 글보다 먼저 전달한다. 넘어가기 표시가 없으면 플레이어는 대화가 끝났는지 로딩 중인지 구분하지 못해 애매하게 기다리게 되므로, 이 신호는 생략하면 안 되는 요소다.

언제 쓰나

NPC 대사, 컷신 자막, 튜토리얼 안내문처럼 순차적으로 읽혀야 하는 텍스트 전반.