새 캐릭터를 넣었는데 이미지가 안 떴다. 파일은 있고 이름도 맞아 보였다.
Table of contents
Open Table of contents
이름으로 파일을 찾고 있었다
캐릭터 이미지를 이름 규칙으로 조립해 불러오고 있었다. 그때 CCString 에는 포맷 함수가 없어서 snprintf 로 직접 만들었다.
char path[128];
snprintf(path, sizeof(path), "char/%s_%02d_%s.png",
charId.c_str(), level, action.c_str());
CCSprite* sp = CCSprite::spriteWithFile(path);
레벨을 두 자리로 채우게 돼 있는데 새로 넣은 파일은 한 자리였다. 이름이 한 글자 달라서 못 찾았다. 파일도 있고 코드도 맞는데 둘이 서로를 못 찾는 상태다.
못 찾아도 조용했다
spriteWithFile() 은 파일이 없으면 NULL 을 돌려주고 오류를 안 던진다. 그것을 화면에 붙이면 죽거나 아무 일도 안 일어나는데 이번엔 후자였다.
나중에 보니 CCTextureCache 가 Couldn't add image 를 이미 찍고 있었다. 로그는 있었고 내가 logcat 을 안 보고 있었던 것이다. 그래도 직접 확인하고 대체 그림을 넣었다.
if (!sp) {
CCLOG("리소스 없음: %s", path);
sp = CCSprite::spriteWithFile("char/placeholder.png");
}
대체 그림이 뜨면 화면에서도 보인다. 아무것도 안 보이는 것과 이상한 그림이 보이는 것 중에는 뒤가 낫다.
규칙을 문서로 적고 검사를 만들었다
이름 규칙이 코드에만 있으니 리소스를 만드는 쪽이 알 방법이 없었다. 문서로 적었는데 그 뒤에도 실수가 나왔다. 그래서 검사 스크립트를 만들었다.
TOTAL=$(ls *.png 2>/dev/null | wc -l)
if [ "$TOTAL" -eq 0 ]; then echo "대상 파일이 없습니다"; exit 1; fi
for f in *.png; do
echo "$f" | grep -qE '^[a-z]+_[0-9]{2}_(idle|walk|attack|hit|die)\.png$' || echo "규칙 위반: $f"
done
대상이 0개면 실패하게 한 것이 중요했다. 빈 폴더에서 돌리면 위반 0개가 나온다. 그것은 통과가 아니라 아무것도 안 본 것이다.
목록 방식과 대소문자
이름 규칙 대신 목록 파일을 두는 방법도 봤다. 이름이 자유롭고 목록에 없으면 바로 아는 대신 파일을 추가할 때마다 목록도 고쳐야 한다.
규칙으로 찾는 방식은 편하고 목록 방식은 확실하다. 파일이 많고 규칙이 단순하면 앞이 맞고 예외가 많으면 뒤가 맞다. 이번에는 규칙을 유지하고 검사를 붙이는 쪽으로 했다.
시험 중에 다른 것도 나왔다. 어떤 파일 이름이 대문자로 시작했는데 개발 컴퓨터에서는 잘 돌다가 기기에 올리니 못 찾았다. 윈도우는 대소문자를 안 가리고 Android 쪽 파일 시스템은 가린다. 검사가 소문자만 허용하니 이것도 같이 걸렸다.
정리
- 이름 규칙으로 자료를 찾으면 규칙이 깨질 때 조용히 실패한다
spriteWithFile()은 없으면NULL을 돌려주므로 확인이 필요하다CCTextureCache는 이미 로그를 찍고 있었고logcat을 안 본 것이었다- 대체 그림을 두면 화면에서도 보인다
- 규칙이 코드에만 있으면 만드는 쪽이 모르므로 문서로 적는다
- 문서만으로는 실수가 나므로 검사 스크립트를 만든다
- 검사는 대상이 0개면 실패하게 한다
- 윈도우는 대소문자를 안 가리고 기기 쪽은 가린다