[달리는 까까] 이미지 사전 로드와 로딩 페이지
- 이미지 사전 로드
게임을 어느 정도 완성한 후 github page를 이용해 게임을 배포해 봤다. 그러자 로컬 환경에서는 확인할 수 없었던 문제들이 발생했는데, 심각한 문제들 중 하나가 바로 이미지 로딩 시간으로 인한 깨짐이었다.
로컬 환경에서는 이미 모든 이미지가 캐시로 저장되어 있어 문제가 없었다. 그러나 처음 플레이하는 환경에서는 쿠키의 여러 모션(점프, 슬라이드 등)이 빠르게 로딩되지 않아 키를 처음 눌렀을 때는 쿠키가 사라졌다가 두 번째 눌러야 이미지와 애니메이션이 제대로 보이는 상황이 발생했다. 뿐만 아니라 스테이지가 변경되었을 때 배경 이미지와 바닥 이미지가 나타나는 데도 많은 시간이 걸렸다.
이 문제를 해결하기 위해 이미지 사전 로드 기법을 이용했다.
const loadImg = () => {
//이미지 미리 로드
const preLoadImgSrc = [
"./lib/lobby/The Witch's Kitchen.png",
"./lib/images/gingerMK_profile.png",
"./lib/lobby/notice.png",
"./lib/ranks/No_rank.png",
"./lib/ranks/rank_Guide.PNG",
"./lib/images/gingerMK_run.png",
"./lib/images/gingerMK_slide.png",
"./lib/images/gingerMK_jump_one.png",
"./lib/images/gingerMK_jump_double.png",
"./lib/images/gingerMK_jump_down.png",
"./lib/images/gingerMK_crashed3.png",
"./lib/images/gingerMK_dead.png",
"./lib/jelly/blue_jelly_bean.png",
"./lib/jelly/yellow_bear_jelly.png",
"./lib/jelly/pink_bear_jelly.png",
"./lib/jelly/blue_bear_jelly.png",
"./lib/jelly/big_bear_jelly.png",
"./lib/obstacles/clock.png",
"./lib/obstacles/pink_crystal.png",
"./lib/obstacles/snacks.png",
"./lib/obstacles/cake1.png",
"./lib/obstacles/table.png",
"./lib/obstacles/green_crystal.png",
"./lib/obstacles/mini_snack.png",
"./lib/obstacles/lamp.png",
"./lib/obstacles/long_crystal.png",
"./lib/obstacles/knife.png",
];
preLoadImgSrc.forEach((arr) => {
const img = new Image();
img.src = arr;
if (arr === preLoadImgSrc[preLoadImgSrc.length - 1]) {
img.onload = () => {
document.querySelector(".loading_box").style.display = "none";
};
}
});
};
이비지 사전 로드 기법에 대한 설명은 이전 포스팅에서 확인할 수 있다.
https://ant-hill.tistory.com/93?category=1073273
JS Image preloading
웹 페이지를 변경하거나 다른 페이지로 이동할 경우 이미지가 많거나 크기가 커서 시간이 오래 걸릴 때 사용하는 방법이다. 사용자의 요청이 들어오기 전에 이미지를 미리 로드해 캐시로 이미
ant-hill.tistory.com
- 로딩 페이지
위의 코드는 lobby.js에 있는 코드로 게임에 접속하면 처음 뜨는 메인 화면인 로비에서 실행되는 코드다. 이미지가 모두 로딩된 후 게임을 플레이할 수 있도록 하는 것이 목적이기 때문에 로딩 페이지를 추가했다.
전체 화면 크기의 로딩 박스를 덮어씌웠다가 모든 이미지가 로딩되면 .loading_box의 display를 none으로 바꿔준다.
지금 코드를 다시 보니, 모든 이미지가 로드되었을 때 로딩 화면을 없애는게 아니라 마지막 이미지가 로드되면 로딩화면을 없애게 구현되어 있다.
forEach에서 각 이미지를 비동기적으로 시작하지만, 각각의 로드 완료 시점을 기다리지 않고 마지막 이미지의 onload 이벤트에만 로딩을 끝내는 로직을 넣어놨기 때문이다.
모든 이미지의 로드를 파악하기 위해 아래와 같이 수정했다.
const loadImg = async () => {
const preLoadImgSrc = [
// 이미지 파일 경로 배열
];
const loadImage = (src) => new Promise((resolve, reject) => {
const img = new Image();
img.src = src;
img.onload = resolve;
img.onerror = reject;
});
try {
await Promise.all(preLoadImgSrc.map(src => loadImage(src)));
document.querySelector(".loading_box").style.display = "none";
} catch (error) {
console.error("이미지 로드 실패:", error);
}
};
예전에는 Promise가 뭔지도 몰랐는데... 잘 성장했구나...
🔻모든 코드 보기🔻
https://github.com/mkthebea/CCKK_Run.git
GitHub - mkthebea/CCKK_Run: A fangame of [CookieRun: Ovenbreak]
A fangame of [CookieRun: Ovenbreak]. Contribute to mkthebea/CCKK_Run development by creating an account on GitHub.
github.com
🔻게임 하기🔻
https://mkthebea.github.io/CCKK_Run/
DAL GGA
Loading... No Record Bronze Silver Gold Ruby Diamond Rainbow
mkthebea.github.io