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]로 꺼내서 사용하면된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

분석하고 보니 별거 아니지만...

이렇게 체계적으로 코딩을 한다는 것 자체가 능력자느님들과 나의 차이같다.

 

 

 

 

 

 

 

 

 

 

 

Posted by 커널제로

본 블로그는 페이스북 댓글을 지원합니다.

,