반응형

cocos2d-x에서 std::thread를 이용하여  multi thread를 사용하다보면 종종 에러가 나는 경우가 있습니다.

그 이유는 cocos object들이 별도의 thread를 돌리고 있기 때문인데 특히 통신 부분에서 많이 문제가 

발생하는 것 같습니다.


게임 만들다보면 thread를 꼭 써야 하는 예를 들어 로딩화면에서 로딩 프로그레스가 계속 돌면서 이미지를 

로드한다거나 사운드를 로드한다거나 하면 쓰레드를 쓰지 않고 그냥 실행시 로딩 프로그레스가 멈춰 있는

문제가 발생합니다. 


문제가 있는데 그럼 cocos2d는 thread를 쓰지 말라는 건가요?

아닙니다. 그래서 cocos2d-x scheduleer에서 편하게 사용할 수 있도록 만들어 놨습니다.

당연히 mutex도 걸려 있습니다.


저 같은 경우 Json Parsing에 이용하였는데 보통은 Game Loading부분에 많이 이용 합니다.

요즘 TextureCache::addImageAsync 라는 기능이 있어 이미지 로딩부분이 더 편해졌습니다만

그래도 알아보도록 하죠.


#include "HelloWorldScene.h"

 

USING_NS_CC;

 

Scene* HelloWorld::createScene()

{

    // 'scene' is an autorelease object

    auto scene = Scene::create();

    

    // 'layer' is an autorelease object

    auto layer = HelloWorld::create();

 

    // add layer as a child to scene

    scene->addChild(layer);

 

    // return the scene

    return scene;

}

 

// on "init" you need to initialize your instance

bool HelloWorld::init()

{

    //////////////////////////////

    // 1. super init first

    if ( !Layer::init() )

    {

        return false;

    }

    

    Size visibleSize = Director::getInstance()->getVisibleSize();

    Vec2 origin = Director::getInstance()->getVisibleOrigin();

 

    /////////////////////////////

    // 2. add a menu item with "X" image, which is clicked to quit the program

    //    you may modify it.

 

    // add a "close" icon to exit the progress. it's an autorelease object

    auto closeItem = MenuItemImage::create(

                                           "CloseNormal.png",

                                           "CloseSelected.png",

                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));

    

    closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,

                                origin.y + closeItem->getContentSize().height/2));

 

    // create menu, it's an autorelease object

    auto menu = Menu::create(closeItem, NULL);

    menu->setPosition(Vec2::ZERO);

    this->addChild(menu, 1);

 

    /////////////////////////////

    // 3. add your codes below...

 

    // add a label shows "Hello World"

    // create and initialize a label

    

    auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);

    

    // position the label on the center of the screen

    label->setPosition(Vec2(origin.x + visibleSize.width/2,

                            origin.y + visibleSize.height - label->getContentSize().height));

 

    // add the label as a child to this layer

    this->addChild(label, 1);

 

    // add "HelloWorld" splash screen"

    auto sprite = Sprite::create("HelloWorld.png");

 

    // position the sprite on the center of the screen

    sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

 

    // add the sprite as a child to this layer

    this->addChild(sprite, 0);

    

    

    std::string data;

    

    // 스케줄러에 Thread로 이용할 함수를 넣어준다.

    // 인자값도 편하게 넘길 수 있어 사용하기 좋다.

    auto scheduler = Director::getInstance()->getScheduler();

    scheduler->performFunctionInCocosThread(CC_CALLBACK_0(HelloWorld::JsonParsingList, this, data));

    

    

    return true;

}

 

 

void HelloWorld::menuCloseCallback(Ref* pSender)

{

    Director::getInstance()->end();

 

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

    exit(0);

#endif

}

 

void HelloWorld::JsonParsingList(std::string data)

{

    //Json Parsing 작업을 하면 됩니다.

}


주석을 달아 놓았습니다. 분석하시기 편하실 겁니다. 

Json파싱 외에도 여러 부분에 사용할 수 있는데 가장 대표적인 예가 리소스 로딩 부분일 것 같습니다.


코코스가 무료 엔진 중에 정말 잘 만들어진 것 같습니다.

코코스를 계속 사용하다보면 정말 무궁무진한 기능들이 내포 되어 있습니다.

하지만 우리는 cocos2d-x에는 엄청 많은 기능이 있는데 모르고 넘어가는 때가 많습니다.


다음 포스팅은 파일 다운로드에 대해 써볼까 합니다.

3.9버전에서 curl사용을 안하고 Downloader를 만들었더라구요 

사용해 봤는데 쉽고 좋내요 ^^

시간되는대로 올려 보겠습니다.


반응형

+ Recent posts