CCSpriteFrameCache.class 파일에서 어떠한 원리로 plist 이미지를 불러오는지 파악해보았다.
public Set addSpriteFramesEx(String plist)
{
String texturePath = null;
int i = plist.lastIndexOf('.');
if(i > 0 && i <= plist.length() - 2)
{
texturePath = (new StringBuilder(String.valueOf(plist.substring(0, i)))).append(".png").toString();
}
CCTexture2D texture = CCTextureCache.sharedTextureCache().addImageExternal((new StringBuilder(String.valueOf(CCDirector.ex_image_path))).append(texturePath).toString());
return addSpriteFrames(plist, texture);
}
일단, 위의 함수에서 plist 풀네임(확장자포함)을 받아서 .plist 혹은 .xml을 제거 하고 동일한 이름에
.png 확장자를 가진 이미지를 텍스쳐로 설정한뒤
아래의 함수를 호출하게 된다.
*별 다른건 없고 중간에 if문으로 texturePath를 설정할때 조건이 두개가 들어가는데
plist 파일이 병신인지 아닌지만 판단한뒤 (확장자가 없거나.. 파일명길이가 0이거나 0보다 작을때 - 0보다 작은 경우는 없으니 결국 확장자가 없거나 파일이 없으면 try catch가 없으니 그냥 오류를 뿜고 다운 혹은 오작동 하겠지..
public Set addSpriteFrames(String plist, CCTexture2D texture)
{
HashMap dict = PlistParser.parse(plist);
return addSpriteFrames(dict, texture);
}
이 함수는 plist를 파싱해서 해쉬맵과 텍스쳐로 나눠 담아서
동일한 이름의 함수를 호출한다. 오버로딩 존나 좋아하는 새끼들이 만들었나보다.
사람 헷깔리게 그냥 다른 함수명 쓰지
* PlistParser 클래스를 까봤는데 얘도 영 복잡하네 일단그냥 넘어가자
public Set addSpriteFrames(HashMap dictionary, CCTexture2D texture)
{
HashMap metadataDict = (HashMap)dictionary.get("metadata");
HashMap framesDict = (HashMap)dictionary.get("frames");
int format = 0;
if(metadataDict != null)
format = ((Integer)metadataDict.get("format")).intValue();
if(format < 0 || format > 3)
ccMacros.CCLOGERROR("CCSpriteFrameCache", "Unsupported Zwoptex plist file format.");
java.util.Map.Entry frameDictEntry;
CCSpriteFrame spriteFrame;
for(Iterator iterator = framesDict.entrySet().iterator(); iterator.hasNext(); spriteFrames.put((String)frameDictEntry.getKey(), spriteFrame))
{
frameDictEntry = (java.util.Map.Entry)iterator.next();
HashMap frameDict = (HashMap)frameDictEntry.getValue();
spriteFrame = null;
if(format == 0)
{
float x = ((Number)frameDict.get("x")).floatValue();
float y = ((Number)frameDict.get("y")).floatValue();
float w = ((Number)frameDict.get("width")).floatValue();
float h = ((Number)frameDict.get("height")).floatValue();
float ox = ((Number)frameDict.get("offsetX")).floatValue();
float oy = ((Number)frameDict.get("offsetY")).floatValue();
int ow = 0;
int oh = 0;
try
{
ow = ((Number)frameDict.get("originalWidth")).intValue();
oh = ((Number)frameDict.get("originalHeight")).intValue();
}
catch(Exception e)
{
ccMacros.CCLOG("cocos2d", "WARNING: originalWidth/Height not found on the CCSpriteFrame. AnchorPoint won't work as expected. Regenerate the .plist");
}
ow = Math.abs(ow);
oh = Math.abs(oh);
spriteFrame = CCSpriteFrame.frame(texture, CGRect.make(x, y, w, h), Boolean.valueOf(false), CGPoint.make(ox, oy), CGSize.make(ow, oh));
} else
if(format == 1 || format == 2)
{
CGRect frame = GeometryUtil.CGRectFromString((String)frameDict.get("frame"));
boolean rotated = false;
if(format == 2)
rotated = ((Boolean)frameDict.get("rotated")).booleanValue();
CGPoint offset = GeometryUtil.CGPointFromString((String)frameDict.get("offset"));
CGSize sourceSize = GeometryUtil.CGSizeFromString((String)frameDict.get("sourceSize"));
spriteFrame = CCSpriteFrame.frame(texture, frame, Boolean.valueOf(rotated), offset, sourceSize);
} else
if(format == 3)
{
CGSize spriteSize = GeometryUtil.CGSizeFromString((String)frameDict.get("spriteSize"));
CGPoint spriteOffset = GeometryUtil.CGPointFromString((String)frameDict.get("spriteOffset"));
CGSize spriteSourceSize = GeometryUtil.CGSizeFromString((String)frameDict.get("spriteSourceSize"));
CGRect textureRect = GeometryUtil.CGRectFromString((String)frameDict.get("textureRect"));
boolean textureRotated = ((Boolean)frameDict.get("textureRotated")).booleanValue();
spriteFrame = CCSpriteFrame.frame(texture, CGRect.make(textureRect.origin.x, textureRect.origin.y, spriteSize.width, spriteSize.height), Boolean.valueOf(textureRotated), spriteOffset, spriteSourceSize);
}
}
return framesDict.keySet();
}
이 쥰내 길고 복잡한듯 보이는 함수는
쉽게 말해 plist 파일을 읽어서 큰 이미지를 잘라서 plist에 설정된 이미지를 조각조각 내서 캐쉬에
담아둔다는 내용이다.
for (int i = 0; i < cut; i++)
{
String str = String.format("a%02d.png", i);
spArray[i] = CCSprite.sprite(mCache.getSpriteFrame(str));
strTag[i] = str;
}
이제 이걸 이딴 식으로 spArray - CCSprite[cut] 에 담은뒤에
spArra[i]로 꺼내서 사용하면된다.
분석하고 보니 별거 아니지만...
이렇게 체계적으로 코딩을 한다는 것 자체가 능력자느님들과 나의 차이같다.
본 블로그는 페이스북 댓글을 지원합니다.