PIXI.Assets 리소스 불러오기
천둥상어
·2024. 2. 5. 13:43
개발을 하다 보면
외부에서 리소스들을 불러와야 하는 경우가 있다.
방법은 순수 자바스크립트로 구현할 수도 있고,
로더 라이브러리를 사용할 수도 있다.
이때 순수 자바스크립트로 구현한다면
신뢰성은 보장 받지만
큰 규모의 개발 환경에서는 따로 매니징을
해주는 코드단을 개발해야 한다.
라이브러리를 사용한다면 편의성은 좋지만
리소스 종류에 따라서 각기 다른 로더 라이브러리를
설치해야 하거나 버전에 따라서 오작동 될 수도 있다.
하지만 Pixi.js 기반의 캔버스 앱을 개발한다면
Pixi.js 설치만으로도 쉽게 리소스들을 로드할 수 있다.
Pixi.js는 이미지, 폰트, JSON 파일을 읽을 수 있는 Assets 클래스가 존재한다.
PIXI.Assets.load() 로드
아래는 Assets.load() 메소드를 호출하여 폰트와 이미지를 불러오는 코드이다.
분홍색 토끼 텍스처와 'ATROX' 폰트를 로드해 렌더링 해주고 있다.
import * as PIXI from "pixi.js";
export default class Test_Loader extends PIXI.Container {
constructor() {
super();
this.init();
}
async init() {
// 텍스처 로드
const spr = new PIXI.Sprite();
spr.texture= await PIXI.Assets.load('resource/textures/pink-rabbit.png');
spr.scale.x = 0.5;
spr.scale.y = 0.5;
spr.x = 200 - spr.width / 2;
spr.y = 200 - spr.height / 2;
this.addChild(spr);
// 폰트 로드
const font_ARTOX = await PIXI.Assets.load('resource/font/ATROX.TTF');
const style = new PIXI.TextStyle({
fill: 'pink',
fontSize: 50,
fontFamily:'ATROX'
});
const txt = new PIXI.Text('Pink Rabbit', style);
txt.x = 200 - txt.width / 2;
this.addChild(txt)
}
}
PIXI.Assets.cache 캐싱
로드된 리소스들은 캐싱이 가능하다.
로드할 때, alias(별칭)과 src(경로)를 아래 코드처럼 넣어주면
Assets.cache.get(별칭)으로 해당 리소스를 가져올 수 있다.
await PIXI.Assets.load({alias:'pink_rabbit',src:'resource/textures/pink-rabbit.png'});
const spr = new PIXI.Sprite();
spr.texture= PIXI.Assets.cache.get('pink_rabbit');
spr.scale.x = 0.5;
spr.scale.y = 0.5;
spr.x = 200 - spr.width / 2;
spr.y = 200 - spr.height / 2;
this.addChild(spr);
Manifest 리소스 관리
매니페스트를 작성해서 묶음(bundle)으로 관리할수도 있다.
매니페스트는 모든 자산과 해당 속성의 목록을 포함하는 JSON 형태이다.
번들은 리소스를 그룹화 하여 필요시 한번에 로드할 수 있다.
manifest를 등록했다고 해서 메모리상에 로드가 바로 되지는 않는다.
묶음 전체를 로드한다면 Assets.loadBundle() 메서드로 로드하거나,
개별로 로드 한다면 Assets.load() 메서드로 로드를 해줘야 한다.
아래 코드는 manifest 상수를 하나 선언해서 그룹화된 리소스 정보를 넣어주고,
Assets.init() 메서드로 manifest 등록 후, 로드하는 과정을 보여준다.
Assets.loadBundle('font')로 'ATROX', 'BMJUA' 폰트를 불러와서
처음과 다르게 '안녕' 이란 글씨를 추가 렌더링 하고 있다.
import * as PIXI from "pixi.js";
const manifest = {
bundles:[
{
name: 'font',
assets: [
{
alias: 'ATROX',
src: 'resource/font/ATROX.ttf'
},
{
alias: 'BMJUA',
src: 'resource/font/BMJUA.ttf'
}
],
},
{
name: 'texture',
assets: [
{
alias: 'pink_rabbit',
src: 'resource/textures/pink-rabbit.png'
}
],
}
]
}
export default class Test_Loader extends PIXI.Container {
constructor() {
super();
this.init();
}
async init() {
// 매니페스트 등록
await PIXI.Assets.init({manifest});
// 폰트 로드
await PIXI.Assets.loadBundle('font');
// 텍스처 로드
await PIXI.Assets.loadBundle('texture');
// 텍스처
const spr = new PIXI.Sprite();
spr.texture= PIXI.Assets.cache.get('pink_rabbit');
spr.scale.x = 0.5;
spr.scale.y = 0.5;
spr.x = 200 - spr.width / 2;
spr.y = 200 - spr.height / 2;
this.addChild(spr);
// 텍스트
const style_0 = new PIXI.TextStyle({
fill: 'pink',
fontSize: 50,
fontFamily:'ATROX'
});
const txt_0 = new PIXI.Text('Pink Rabbit', style_0);
txt_0.x = 200 - txt_0.width / 2;
this.addChild(txt_0);
const style_1 = new PIXI.TextStyle({
fill: 'orange',
fontSize: 30,
fontFamily:'BMJUA'
});
const txt_1 = new PIXI.Text('안녕?', style_1);
txt_1.x = 300;
txt_1.y = 230;
this.addChild(txt_1);
}
}
Manifest 목록을 JSON 파일로 가져오기
위의 코드에서는 상수로 매니페스르 목록을 구현했다.
하지만 실 개발에서는 매니페스트 목록도 외부에 위치할 가능성이 높다.
우선 매니페스트 정보를 별도의 json 파일로 만든다.
manifest.json 작성
{
"bundles":[
{
"name": "font",
"assets": [
{
"alias": "ATROX",
"src": "resource/font/ATROX.ttf"
},
{
"alias": "BMJUA",
"src": "resource/font/BMJUA.ttf"
}
]
},
{
"name": "texture",
"assets": [
{
"alias": "pink_rabbit",
"src": "resource/textures/pink-rabbit.png"
}
]
}
]
}
manifest.json 로드
JSON 파일 역시 Assets.load() 메서드를 사용하여 로드할 수 있다.
await PIXI.Assets.load('resource/manifest.json');
그래서 로드한 json 정보를 Assets.init() 에 넘겨주면 된다고 생각했다.
하지만 예상과는 다르게 에러가 발생했다.
정확한 이유는 모르겠지만
Assets.init() 메서드가 전역적인 초기화 처리를 하기 때문으로 보인다.
정리하면 Assets.init() 메서드를 사용한다면
그 전에 Assets.load() 사용하면 안된다.
그래서 매니페스트용 json은 fetch() 메서드로 불러들인 후
Assets.init() 메서드에 넘겨줬다.
// 매니페스트 json 불러오기
const data = await fetch('resource/manifest.json');
const manifest = await data.json();
여기서 주의점이 하나 있는데
값을 넘겨줄때 manifest 이름으로 넘겨줘야 한다.
코드 내부 규칙이다.
await PIXI.Assets.init({manifest});
코드의 통일성이 아쉽지만 manifest.json을 fetch()로
로드하여 넘겨주니 매니페스트가 잘 등록되었다.
import * as PIXI from "pixi.js";
export default class Test_Loader extends PIXI.Container {
constructor() {
super();
this.init();
}
async init() {
// 매니페스트 json 불러오기
const data = await fetch('resource/manifest.json');
const manifest = await data.json();
// 매니페스트 등록
await PIXI.Assets.init({manifest});
// 폰트 로드
await PIXI.Assets.loadBundle('font');
// 텍스처 로드
await PIXI.Assets.loadBundle('texture');
// 텍스처
const spr = new PIXI.Sprite();
spr.texture= PIXI.Assets.cache.get('pink_rabbit');
spr.scale.x = 0.5;
spr.scale.y = 0.5;
spr.x = 200 - spr.width / 2;
spr.y = 200 - spr.height / 2;
this.addChild(spr);
// 텍스트
const style_0 = new PIXI.TextStyle({
fill: 'pink',
fontSize: 50,
fontFamily:'ATROX'
});
const txt_0 = new PIXI.Text('Pink Rabbit', style_0);
txt_0.x = 200 - txt_0.width / 2;
this.addChild(txt_0);
const style_1 = new PIXI.TextStyle({
fill: 'orange',
fontSize: 30,
fontFamily:'BMJUA'
});
const txt_1 = new PIXI.Text('안녕?', style_1);
txt_1.x = 300;
txt_1.y = 230;
this.addChild(txt_1);
}
}
주의점
며칠동안 Assets 사용하면서 알게된 문제점이 있다.
JSON 파일은 Assets.load() 로 로드시 안전성을 보장 받지 못한다.
예를 들어 Spine 데이터 JSON 파일을 읽어들이면
Spine 데이터에서만 사용되는 JSON 구조를 감지하고
SpineData로 인식을 하는데...
Spine의 추출 버전에 따라서
로드시 에러가 발생할 수 있다.
그렇기에 Assets.load()로 JSON 파일을 불러와야 한다면
동일 구조의 JSON 파일을 정상적으로 로드하는지
사전 테스트를 꼭 해야 될것 같다.
'프로그래밍 > Pixi.js7' 카테고리의 다른 글
PIXI.AnimatedSprite #2 애니메이션 이벤트 (0) | 2024.03.02 |
---|---|
PIXI.AnimatedSprite #1 애니메이션 재생 (0) | 2024.02.18 |
PIXI.Assets 로드된 이미지에서 특정 영역만 렌더링하기 (1) | 2024.02.14 |
PIXI-ANIMATE 환경 설정 (0) | 2024.01.17 |
Pixi.js 텍스트 렌더링 (0) | 2024.01.08 |