Cocos2d-x 3.2에서 디렉토리의 파일 목록을 얻고 싶은 이야기

8590 단어 C++cocos2d-x

소개



이것은 Cocos2d-x Advent Calendar 2014의 21 일째 기사입니다.

예정으로 "가로 스크롤 게임에 대해 씁니다"라고 말했다. 그건 거짓말이다.


죄송합니다. 다른 글을 쓰고 싶은 재료가 떠오르기 때문에 그쪽에 대해 씁니다.
Cocos2d-x에서 Resources의 하위 디렉터리에 있는 파일 목록을 가져오는 방법에 대해 알아봅니다.
버전은 3.2를 대상으로 합니다.

Cross Platform 수 있습니까? → 할 수 없다!



이것은 꽤 필요한 기회도 많을 것이므로, FileUtils 당에 API 가 준비되고 있을 것이라고 생각했습니다만, 아무래도 그렇지 않은 것 같습니다.
스택 오버 플로우 에,

There is no cross platform API in cocos2dx for listing directory contents. You can store file names in an array while creating them.

라고 대답하는 분이 계십니다.
이번에는 iOS와 Android에 대해 하고 싶었기 때문에 각각 다른 방법이 필요합니다.
어떻게든 양쪽 플랫폼에서 실현할 수 있었으므로, 이하에 써 가려고 생각합니다.

대상 디렉토리는 Cocos2d-x의 Resources에 포함되어 있다고 가정합니다.

iOS에서는 어떻게합니까?



iOS 쪽을 솔직하게 구현할 수 있습니다.
전체 경로를 얻은 후 C 언어 표준 opendir 함수에서 디렉터리를 엽니다. DIR 구조체에서 readdir() 로 디렉토리 내용을 나타내는 구조체 dirent 로 받으면 내용의 파일 이름을 검사합니다.

샘플 코드는 다음과 같습니다.

std::vector<std::string> getDirContents(std::string dirname) {
    FileUtils* fu = FileUtils::getInstance();

    std::string dir = fu->fullPathForFilename(dirname);

    std::vector<std::string> list;

    DIR* dp;
    struct dirent* ent;

    if ((dp = opendir(dir.c_str()), "r") == NULL) {
        CCLOGERROR("ディレクトリが開けません。:%s", dir.c_str());
        perror(dir.c_str());
        return list;
    }

    while ((ent = readdir(dp)) != NULL) {
        CCLOG("ファイル:%s", ent->d_name);
        list.push_back(ent->d_name);
    };
    closedir(dp);

    return list;
}


Android에서는 어떻게 해야 하나요?



Android에서는 fullPathForFilename() 메서드에서 전체 경로를 잘 사용할 수 없습니다.
그러면 opendir() 함수도 사용할 수 없습니다. Android/C++ 에서는 Resources 부하는 JNI 의 AssetsManager 라고 하는 것으로 취급하는 것 같습니다.
AssetsManager 의 인스턴스의 취득에는 어플리케이션의 Context 가 필요하게 되는 것 같고, 조금 귀찮습니다. 이번에는 Cocos2d-x의 FileUtils가 private 변수로 가지고 있는 인스턴스를 빌려 왔습니다. (일단 public으로 다시 작성했습니다.)

샘플 코드는 다음과 같습니다.

std::vector<std::string> getDirContents(std::string dirname) {

    std::vector<std::string> list;

    AAssetManager* mgr = FileUtilsAndroid::assetmanager;

    AAssetDir* assetDir = AAssetManager_openDir(mgr, dirname.c_str());
    if (!assetDir) {
        CCLOGERROR("ディレクトリが開けません:%s", dirname.c_str());
        return list;
    }

    const char* filename = NULL;
    while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
        CCLOG("ファイル:%s", filename);
        list.push_back(filename);
    }
    AAssetDir_close(assetDir);

    return list;
}


결론



Cocos2d-x에서 Resources 디렉토리의 파일 목록을 가져오는 iOS, Android에 대한 이야기를 작성했습니다. 자신으로서는 필요한 기회도 많다고 생각하기 때문에, FileUtils 근처에 실장되면 좋겠다-라고 생각한 대로.

읽어 주셔서 감사합니다.

좋은 웹페이지 즐겨찾기