Pixi JS를 사용한 로직의 본체
const imageCache: Record<string, HTMLImageElement> = {};
- 이미지 URL을 저장해놓은 캐시 객체
- 이미지를 수시로 로드하면 부하가 많이 걸림
- 캐시에다가 미리 저장할 수 있는 객체
- 한번 로드된 이미지는 다시 필요할 때 빠르게 쓸 수 있도록 함
export enum AnimationState {
IDLE = "idle",
MOVING = "moving",
HIT = "hit",
DEAD = "dead",
VICTORY = "victory",
GAME_OVER = "gameOver",
ATTACK = "attack",
}
// 이미지 사전 로딩 함수 (단일 이미지)
const preloadImage = (src: string): Promise<HTMLImageElement> => {
return new Promise((resolve, reject) => {
// 이미 캐시에 있으면 바로 반환
if (imageCache[src]) {
resolve(imageCache[src]);
return;
}
const img = new Image();
img.crossOrigin = "anonymous"; // CORS 문제 해결
img.onload = () => {
imageCache[src] = img;
resolve(img);
};
img.onerror = (e) => {
console.error(`이미지 로드 실패: ${src}`, e);
reject(e);
};
img.src = src;
});
};
// 이미지 사전 로딩 함수 (여러 이미지)
const preloadImages = (sources: string[]): Promise<HTMLImageElement[]> => {
const promises = sources.map((src) => preloadImage(src));
return Promise.all(promises);
};
- 단일 이미지는 spriteSheet, 여러 이미지는 imageSequence를 의미함
- spriteSheet는 여러 프레임이 한 파일에 다 들어가 있음
- imageSequence는 프레임마다 파일로 나누어져 있음
export interface ... // 정의된 인터페이스들
- 아래 애니메이션 인터페이스들은 옵션 타입으로 (sprite + 공통) 애니메이션과 (sequence + 공통) 애니메이션 두 가지로 정의됨
// 애니메이션 훅 반환 타입
export interface UseGameAnimationReturn {
isLoaded: boolean;
initializeApp: (container: HTMLDivElement) => PIXI.Application | null;
playAnimation: (play: boolean) => void;
cleanup: () => void;
appRef: React.MutableRefObject<PIXI.Application | null>;
changeAnimationState: (state: AnimationState) => void;
currentState: AnimationState;
setHP: (hp: number) => void;
setTimeRemaining: (seconds: number) => void;
}
- 훅의 속성들
isLoaded
: 로딩중인지 아닌지
initializeApp
: 새로운 PIXI 앱 (초기화)
playAnimation
: 애니메이션을 플레이하는 함수
cleanup
: 앱 삭제(언마운트)
appRef
: pixiJS 앱의 인스턴스를 담아두는 Ref
changeAnimationState
: 캐릭터의 애니메이션 상태를 변경하는 함수
currentState
: 현재 캐릭터의 애니메이션 상태
setHP
: HP 세팅
setTimeRemaining
: 타이머 세팅