Phaser 3 에셋을 데이터 URI로 로드

이 블로그 포스트에서는 xhr 요청에 의존하지 않고 Phaser 3 게임의 자산을 데이터 URI로 로드하는 방법을 설명합니다. 이미지, 스프라이트 시트 및 오디오에 대해 설명하겠습니다.

Phaser 3에서 애셋 (이미지 및 오디오와 같은)을 로드하는 것은 xhr 요청을함으로써 이루어집니다. 웹용 게임을 제작한다면 괜찮습니다. 그러나 게임이 서버에서 호스팅되지 않고 로컬 파일 시스템에서로드해야하는 경우 모든 문제가 발생합니다. file : // scheme을 사용하여 html 파일을 열 때 Javascript는 이러한 종류의 요청을 할 수 없습니다.

데이터 URI를 사용하여이를 해결할 수 있습니다. 그것들은 base64로 인코딩 된 문자열로 표현되는 기본적으로 완전한 이미지 (또는 다른 파일)이며 외부 파일로 로드되는 대신 코드에 병합 될 수 있습니다. 다음은 그러한 코드의 작은 예입니다.
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAAU0lEQVQoU2NkIBEwkqiegTINJtNvH2BgYGg4k6kKorECFBtMZtz+D1V1gOE/QyM2jbg0wEzH0Ihfw3+Gg+hOxK4Bi0KYlagaSPU0MXFCWTwQYwMA3P8mDXcTncUAAAAASUVORK5CYII=" />

경고 : 로컬 컴퓨터에서 게임을 개발하는 경우 Node.js로 웹 서버를 에뮬레이트하는 것이 가장 좋습니다. 게임의 최종 간행물이 웹상에 있을 경우 여기에 설명 된 기술은 피해야합니다. 그 이유는 최종 자바 스크립트 파일이 정말로 커질 것이기 때문입니다.

나는 여기에서 찾을 수있는 주석 처리 된 소스 코드로 완전한 예제를 만들었다 : https://github.com/Quinten/phaser-3-assets-as-data-uri

이 예제는 phaser3-project-template에서 시작되었습니다. 따라서 프로젝트가 Webpack과 비슷한 시작점을 사용한다면 잘 할 수 있습니다.


자산을 데이터 URI 문자열로 변환

먼저 자산을 base64로 인코딩 된 문자열로 변환 할 방법이 필요합니다. 이 작업을 수행 할 수있는 온라인 도구가 많이있을 수 있지만 이러한 문자열을 모두 코드에 복사하여 붙여 넣는 것은 고통스러운 작업이 될 것입니다. 운 좋게도 우리를 위해이 작업을 수행 할 수있는 Webpack 로더가 있습니다. url-loader를 살펴보십시오. 개발 종속성으로 npm을 사용하여 설치하십시오.
npm install url-loader --save-dev

webpack.config.js의 rules 섹션에 다음 코드를 추가해야합니다.
{
    test: /\.(png|mp3)$/,
    use: [{ loader: 'url-loader'}]
}

이제 png 및 mp3 파일을 자바 스크립트 코드로 가져올 수 있으며 로더는 이를 데이터 URI 문자열로 변환합니다.
import blueSrc from '../assets/blue.png'
blueSrc는이 경우 코드에서 사용할 수있는 또 다른 문자열 변수이며 값은 이미지를 나타내는 base64로 인코딩 된 데이터 URI입니다.

표준 프리로드 기능으로 자산을로드하는 Phaser 코드를 살펴 보겠습니다.
this.load.image('bg', 'assets/blue.png');
this.load.spritesheet([{ file: 'assets/shards.png', key: 'shards', config: { frameWidth: 16, frameHeight: 16 } }]);
this.load.audioSprite('sfx', ['assets/sfx.ogg', 'assets/sfx.mp3'], 'assets/sfx.json');

이 blogpost 시작 부분의 img 태그 예제에서 우리는 이제 blueSrc 변수를 파일 경로 'assets / blue.png'에 넣고 한번 만 호출 할 수 있다고 생각할 것입니다. 그러나 페이저 (Phaser)는 이것을 하지 못하게 합니다 (적어도 이 글을 쓰는 시점에는 아닙니다). 페이저가 경고를 발생시킵니다. 로컬 데이터 URI가 지원되지 않으며 이미지를 모두 건너 뜁니다.


Phaser TextureManager 및 캐시에 자산 추가

실제로 로더를 건너 뛰고 애셋을 TextureManager 및 Phaser의 내부 캐시 시스템에 직접 추가해야합니다. 간단한 이미지, 스프라이트 시트 및 audiosprites에 대해 어떻게  했는지 보여 드리겠습니다. 아마도 내 방법은 이 작업을 수행하는 가장 권장 된 방법이 아니지만 결국에는 효과가 있었습니다.

간단한 이미지 추가하기

간단한 이미지의 경우 매우 쉽습니다. blueSrc 데이터 URI가 생기면 한 줄의 코드로 TextureManager에 직접 추가 할 수 있습니다.
this.textures.addBase64('bg', blueSrc);
addBase64는 누락 된 이미지가 있을 때 표시되는 이미지를 추가하기 위해 Phaser에서 내부적으로 사용됩니다.


스프라이트 시트 추가

스프라이트 시트는 조금 더 많은 작업이 필요합니다. TextureManager에는 addSpriteSheet라는 메서드가 있습니다.이 메서드는 키, HTMLImageElement 및 구성 객체의 세 가지 매개 변수를 사용합니다. 그래서 우리는 HTMLImageElement를 만들고 src 속성에 shardsSrc 데이터 URI를 전달합니다. 이것은 onload 메소드를 트리거하고 이미지 요소가 준비되면 TextureManager에 추가됩니다.
var shardsImg = new Image();
shardsImg.onload = () => {
    this.textures.addSpriteSheet('shards', shardsImg, { frameWidth: 16, frameHeight: 16 });
};
shardsImg.src = shardsSrc;


audiosprite 추가하기

내가 사용하는 audiosprites 캐시에서 2 항목 : json 파일 시작 / 중지 데이터 및 AudioBuffer 있습니다. 두 가지 모두가 동일한 키를 가지고 있다면 Phaser는 함께 사용된다는 것을 알고 있습니다. 콜을 하면 자동으로 함께 연결됩니다.
this.sound.playAudioSprite('sfx', 'glass');

json 파일을 캐시에 추가하는 것은 매우 간단합니다. Webpack의 최근 버전은 이미 이 문제를 처리하는 방법을 알고 있습니다. 여기에 URL 로더를 사용할 이유가 없습니다.
import sfxJson from '../assets/sfx.json'

그런 다음 다음 코드 줄을 사용하여 Phaser json 캐시에 저장하십시오.
this.cache.json.add('sfx', sfxJson);

AudioBuffer를 캐시에 추가하는 것은 좀 더 어렵습니다. 왜냐하면 우리가 빠져 나온 base64로 인코딩 된 mp3에서 변환해야 하기 때문입니다.
import sfxSrc from '../assets/sfx.mp3'

우리는 to-array-buffer라는 작은 도우미 함수를 사용할 것이다. 다음과 같이 프로젝트에 설치할 수 있습니다.
npm install to-array-buffer --save

그런 다음 코드로 도우미를 가져 오십시오.
import toArrayBuffer from 'to-array-buffer'

마지막으로 바닐라 자바 스크립트를 사용하여 AudioBuffer를 캐시에 추가합니다.
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
audioCtx.decodeAudioData(toArrayBuffer(sfxSrc), (buffer) => {
    this.cache.audio.add('sfx', buffer);
}, (e) => { console.log("Error with decoding audio data" + e.err); });

이 콜백 순서는, 우선 sfxSrc 데이터 URI를 ArrayBuffer에 디코드 해, ArrayBuffer를 AudioContext에 건네줍니다. AudioContext는, AudioBuffer를 캐쉬에 추가 할 수있는 AudioBuffer로 변환합니다. 'sfx'키는 json 파일과 정확히 같은 키입니다.


Phaser 프리로드 기능에 대한 참고 사항

로더를 사용하지 않고 네트워크에 대한 요청을하지 않기 때문에 장면의 Phaser 사전로드 기능이 즉시 반환되고 장면에 게임 개체를 추가하는 생성 기능이 매우 빨리 호출됩니다. 따라서 우리는 자산을 사용하여 게임 객체를 구성하기 전에 자산이 효과적으로 로드되었는지 확인해야합니다. 그렇지 않으면 게임 개체에 누락 된 이미지가 생깁니다.

장면을 설정하기 전에 모든 onload 및 decodeAudioData 콜백 (위의 코드 에서처럼)이 호출되었음을 추적해야 합니다. github에 있는 예제에서 당신은 내가 이것을 다소 기초적으로 해결했음을 알 수 있습니다.


마무리

이미지, 스프라이트 시트 및 audiosprites를 모두 데이터 URI로 로드하는 작업을 다뤘습니다. 로드해야 하는 다른 유형의 자산이 있는 경우에는 자체적으로 수행해야 합니다. 그러나 원리는 거의 동일 할 것이다.

github에서 작동하는 예제를 찾을 수 있습니다. https://github.com/Quinten/phaser-3-assets-as-data-uri

댓글 없음:

댓글 쓰기