VNLEWIKI이야기를 만들고, 세계를 연결하세요.
한국어
VNLE 사용 설명서

Phaser

← 게임에 콘텐츠 연결하기

Phaser 3.90 · JavaScript

먼저 문장 하나를 화면에 표시해 보세요. 이 작은 예제는 실제 항구 내보내기 파일을 직접 읽으며, 완전한 대화 재생기는 아닙니다. 이후 데이터를 게임 UI에 연결하세요.

1 · 파일 및 장면 준비

하나의 웹 프로젝트에 index.html, first-text.js, story/story.json을 만드세요. script 태그로 first-text.js보다 먼저 Phaser 3.90을 포함하세요. 기존 examples/phaser/phaser.min.js를 사용할 수 있습니다. HTML을 더블클릭하지 말고 로컬 웹 서버로 여세요.

story.json · 내보낸 파일 설명

2 · 첫 번째 텍스트 표시

<!doctype html>
<html lang="en"><meta charset="utf-8"><title>First VNLE text</title>
<script src="phaser.min.js"></script>
<script src="first-text.js"></script></html>

Phaser 3.90 · Phaser 라이선스

class FirstText extends Phaser.Scene {
  preload() {
    this.load.json('story', 'story/story.json');
    this.load.on('loaderror', file => console.error('Cannot load', file.src));
  }
  create() {
    const story = this.cache.json.get('story');
    if (!story) { this.add.text(24, 24, 'Cannot load story.json'); return; }
    const locale = 'en';
    const id = 'fd7b61a3-8233-4ba7-8f77-b88b119a91bf';
    const record = story.content.texts[id];
    const translation = story.content.translations[locale]?.[id];
    const message = translation ? translation.message : record.sourceMessage;
    const text = message.segments.map(segment => {
      if (segment.kind !== 'text') throw new Error('Text-only example');
      return segment.text;
    }).join('');
    this.add.text(24, 24, text, {fontSize: '24px', wordWrap: {width: 720}});
  }
}
new Phaser.Game({type: Phaser.AUTO, width: 800, height: 300, scene: FirstText});

예상 출력은 “Welcome to the harbour. I am Mira.”입니다. locale = "de" 또는 언어 매개변수 de를 사용하면 “Willkommen im Hafen. Ich bin Mira.”가 표시됩니다. 없는 언어는 원문을 사용합니다. 이 예제는 텍스트 세그먼트를 지원하며, 자리표시자를 알림 없이 무시하지 않습니다.

3 · 한 문장에서 대화

위의 고정 텍스트 ID는 첫 번째 테스트용입니다. 게임에서는 story-index.json에서 flowRef/entryRef를 선택하고 execution.entries[entryRef].nodeRef, 이어서 execution.nodes[nodeRef]를 읽으세요. 현재 대화 노드는 text.textRef와 speakerRef를 제공합니다. 다음 진행 방식은 노드 종류에 따라 달라집니다.

이름과 대사: Text.setText(). 답변: Text.setInteractive()와 pointerdown을 사용하며 각 선택지 ID를 유지합니다. End에서는 setVisible(false)로 대화 객체를 숨기고 입력을 비활성화하되 게임 장면은 계속 실행하세요.

  1. Continue와 End: 연결을 따라 진행하고 대화창 닫기
  2. 선택지: 답변 ID, 표시 순서, 선택한 답변의 다음 진행
  3. 조건과 변수: 10 또는 2 골드
  4. 언어: 같은 ID로 새 언어의 콘텐츠 가져오기
  5. 명령: 아이템을 주고 가게를 엽니다.
  6. Call/Return: 하위 이야기로 이동했다가 돌아오기
이 프로그래밍 언어로 답변과 금화 검사 살펴보기

선택지 데이터 읽기

로딩 후 story를 사용할 수 있는 위치에 이 코드를 넣으세요. RPG Maker에서는 const story = $gameTemp.vnleExample.story;를 사용합니다. 확인용으로 ID를 출력하며, 실제 게임에서는 이 출력을 답변 버튼으로 바꾸세요. 항구의 두 답변과 이후 금화 검사를 다루는 예제일 뿐, 범용 해석기는 아닙니다.

// story is already loaded. Keep each optionId on its answer button.
const choice = story.execution.nodes['42edfff8-b8fe-46bf-ae0d-9e2347b6e726'];
for (const optionId of choice.optionOrder) {
  const option = choice.options[optionId];
  console.log(optionId, option.text.textRef); // Resolve text, then create your button.
}
// Inspect the actual purchase check. This particular node is Gold >= 5.
const branch = story.execution.nodes['c1c3c372-0a73-4cd0-851d-ede59d5709bb'];
const gold = 10; // Repeat with 2, using your current game value.
const next = gold >= branch.condition.right.value.value ? branch.whenTrue : branch.whenFalse;
console.log(next.nodeRef);

금화가 10개이면 next는 “Pay five gold”, 2개이면 “Not enough gold”를 가리킵니다. 실제 게임에서는 선택한 경로가 이 노드에 도달했을 때만 검사하세요. 각 답변은 자신의 다음 진행 정보를 제공합니다.

4 · 자신의 이미지 연결하기

이 추가 예제는 현재 대화 객체 node와 주석에 적힌 UI 요소가 있다고 가정합니다. C++와 MonoGame에서는 speakerRef를 이미 SpeakerId 또는 speakerId로 읽은 상태입니다. 키는 미라의 실제 캐릭터 ID이며, 이미지 이름과 위치는 게임에서 정합니다. 표시된 위치에 코드를 넣으세요.

// preload(): the key is a real VNLE character ID; the file is yours.
this.load.image('807b2957-7bab-4a28-83a4-1f3d1589bbc2', 'assets/portraits/mira.png');
// create(): keep one image for the dialogue bar.
this.portrait = this.add.image(100, 180, '807b2957-7bab-4a28-83a4-1f3d1589bbc2').setVisible(false);
// When showing a dialogue; node is your current dialogue object:
const key = node.speakerRef;
this.portrait.setVisible(Boolean(key && this.textures.exists(key)));
if (key && this.textures.exists(key)) this.portrait.setTexture(key);

화자 이름도 대사처럼 content.characters[speakerRef].nameTextRef로 구하세요. 이미지 연결이 없으면 이전 초상화를 숨기거나 대체 이미지를 표시하세요. 이미지는 언어에 따라 선택되지 않습니다.

전체 내보내기의 이미지 참조 사용하기

5 · 게임과 함께 파일 배포하기

JSON과 이미지를 게시할 웹 폴더에 포함하세요. 로더 경로를 설정하지 않았다면 경로는 HTML 페이지 기준입니다. preload는 요청을 대기열에 넣고 create에서 데이터를 사용합니다. 로딩 실패도 확인하세요.

결과 확인

  1. 영어와 독일어 인사말이 올바르게 표시되고, 사용할 수 없는 언어를 선택하면 영어 원문이 표시되어야 합니다.
  2. 진행 로직을 추가했다면 두 답변, 금화 10개와 2개, 하위 이야기에서 돌아오기, End를 시험하세요.
  3. 빌드한 게임을 프로젝트 폴더 밖에서 실행하세요. JSON, 글꼴, 초상화가 그곳에서도 제공되어야 합니다.

공식 문서

API 및 이 접근 방식을 위한 설정 참조: