반응형

cocos2d-x로 게임을 만들수록 새로운 기능들을 알게 되는데 

이번에 새로 알게된 좋은 기능이 있어 소개합니다.

(이미 아는 분들도 있겠지만 ^^ 혹시 저처럼 몰라서 힘들게 돌아가는 길을 택한 분들께 바칩니다.)


애니메이션을 구현하다 보면 노드에 액션을 주고 액션이 끝났을 경우 그 노드를 삭제해야 하는 경우가 있습니다.

어제 까지만 해도 항상 시퀀스를 사용해서 마지막 시퀀스 파라메터에 콜백함수를 주고 노드를 넘겨 삭제를 했었습니다.

(참 바보 같죠 ㅠ_ㅠ)


예를 들어 아래와 같이 구현 했었죠.


void SceneGame::animateBlockMoveDown() // 애니메이션 구현

{

    auto node = Node::create();

    auto actionMove = MoveTo::create(0.3f, Vec2(100, 100));

    auto callbackFunc = CallFuncN::create(CC_CALLBACK_1(SceneGame::callbackBlockMoveDownEnd, this));

   

    auto actionSeq = Sequence::create( actionMove, callbackFuncNULL);


    node->runAction(actionSeq);

}


void SceneGame::callbackBlockMoveDownEnd(cocos2d::Ref *ref)  // 노드 삭제 처리

{

    auto node = dynamic_cast<Node*>(ref);

    node->removeFromParentAndCleanup(true);

}


 문제가 있는 코드는 아닙니다.


콜백함수에서 애니메이션이 끝난 뒤 다른 처리를 하지 않고 노드삭제 처리만 할 거라면 

콜백함수를 만들어야 하는 귀차니즘과 모든 액션에 콜백을 만들어야 한다면 소스코드 또한 지저분해질수 있습니다.

(콜백 함수만... 20개...모두 액션 삭제처리만...물론 노드 삭제처리 콜백 함수 하나만 만들어도 됩니다. ^^)


좀더 깔끔하고 멋진 코드를 위해 사용 하시면 좋을 것 같습니다.


RemoveSelf 액션 함수 사용법에 대해 알아 볼께요.

void SceneGame::animateBlockMoveDown() // 애니메이션 구현 및 노드 삭제 처리

{

    auto node = Node::create();

    auto actionMove = MoveTo::create(0.3f, Vec2(100, 100));

    auto actionRemove = RemoveSelf::create();

    

    auto actionSeq = Sequence::create( actionMove, actionRemove, NULL);


    node->runAction(actionSeq);

}

위 대로 하면 애니메이션 구현 및 노드 삭제처리를 한번에 할 수 있습니다.



update 함수를 보면 아래와 같이 구현 되어 있습니다.

void RemoveSelf::update(float time) 

{

    CC_UNUSED_PARAM(time);

    _target->removeFromParentAndCleanup(_isNeedCleanUp);

}

removeFromParentAndCleanup기능을 하는 액션인거죠. ^^



파라메터로 cleanup 여부를 전달 할 수 있는데 Default가 true로 되어 있습니다.

static RemoveSelf * create(bool isNeedCleanUp = true);



이편한걸 이제야 알았다는게 조금 힘드내요. ^^

사용한지 아직 하루 밖에 안되어서 무슨 문제가 있는지 모르겠지만

문제점을 알고 계신 분은 코멘트 남겨주세요.


감사합니다.

반응형
반응형

cocos2d-x로 개발하다 보면 실제 코딩을 

OSX 유저는 Xcode, Windows 유저는 Visual Studio를 사용 합니다.


저는 Xcode를 사용 하는데 바보 같은 실수를 하여 시간을 낭비했습니다. ㅠ_ㅠ


개발 10년차가 맞는가 하는 오류를 범하고...

혹시나 저와 같이 시간을 낭비하는 분들이 계실까봐 간단하게 글 남깁니다.


저는 아래와 같은 코드를 작성했습니다.

char szDiceFilename[10] = { 0, };

sprintf(szDiceFilename, "dicenum_%d.png", 1);


무엇이 문제 일까요?

무엇 때문에 "stack corruption detected" 에러를 Android에서 발생시키는 걸까요?


벌써 다들 눈치 채셨겠죠? 

메모리 할당을 10byte만 해놓고 13byte를 복사하려고 해서 발생한 문제 입니다.


왜 이런 오류를 범했는가?

컴파일 때는 에러가 발생하지 않습니다.(당연히 컴파일러는 얼만큼 사용할지 모르기 때문이죠^^)

더 큰문제는 Xcode로 컴파일하고 iOS에서 실행을 하면...

두둥...


문제가 발생하지 않습니다.

iOS기기 특성상 부족한 메모리를 자동 할당해주기 때문이죠!!


근데 어디서 문제가 발생하느냐!!

Android 에서 실행시 문제가 발생합니다.


해결 코드 입니다.

char szDiceFilename[32] = { 0, }; //10바이트 할당을 32바이트로 할당

sprintf(szDiceFilename, "dicenum_%d.png"1);


너무 간단한거라 포스팅 하기도 좀 그랬지만.. (사실 창피한게 99%)

혹시나 저 같은 오류를 범하시지 말라고 ^^


메모리를 아껴보겠다는 의지는 아니였지만... 

아무생각 없이 빠르게 개발하다 보면 위와 같은 실수를 할 수 있으니 조심하세요!

반응형
반응형

오늘 급하게 iOS9를 대응하기 위해 

Xcode를 7버전으로 업데이트 하게 되었습니다.


항상 업데이트를 하면 먼가 불안 합니다. 반드시 이전에 없던 에러가 생긴다거나

앱이 실행이 안된다거나 하는 문제가 발생하기 때문입니다.

하지만 업데이트를 하지 않을 수 없죠.


애플같은 경우 일정기간동안 수정할 시간을 주고 그 시간이 지나면 

자신들의 가이드에 맞지 않는 앱들은 검수에서 리젝 당하기 때문입니다. 

그래서 항상 리젝을 피하기 위해 최신버전으로 유지 하는 것이 좋습니다.


물론 한전에 하면돼 라고 생각 하실 수 있겠지만 한번에 하려고 하다보면

더 많은 에러가 발생하고 어떤 문제 때문인지 알기 더 어렵습니다. 


그래서 저는 항상 업데이트가 되면 베타 버전이 아닌 이상에는 최신 버전을 유지하고 있습니다.


그럼 이번 업데이트 하고 나서 어떤 문제가 생기는지 알아 보도록 하겠습니다.


업데이트 하고 나서 제일 처음 발생한 문제는 5.x 버전을 지원하지 않는 다는 점!

아래와 같은 에러가 발생 합니다.


clang: error: -fembed-bitcode is not supported on versions of iOS prior to 6.0


최소 버전을 6.0이상으로 해야 빌드가 되는 건데 5.x 버전을 애플에서 이제 버리는 것 같습니다.

이정도는 문제도 아니죠 ^^ 간단하게 타겟 버전 변경하여 해결 하였습니다.

항상 이정도의 문제면 행복할꺼 같습니다.


General 에서 Target을 6.0 이상으로만 변경 하시면 됩니다.


하지만 이렇게 쉽게 끝내줄 애플이 아니죠. 

해결하고 나니 두번째 문제가 나타납니다.

clang: error: linker command failed with exit code 1 (use -v to see invocation)


무슨 문젠가 검색해 보았습니다.

does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64


아직 자세하게는 모르겠으나.. 대충 BITCODE를 사용하지 않으면 꺼주라는 얘기인거 같아 찾아 보았습니다.

Build Settings -> Build Options 에 가보니 Enable Bitcode라는 것이 있습니다.

Bitcode라는 것이 사용해보진 않았지만 새로 생긴것 같은데 아직 왜 사용해야 하는지는 모르겠습니다.

추후에 다시 포스팅해보도록 하겠습니다.

Enable Bitcode를 No로 해주니 문제해결!



일단은 모든 문제를 해결하고 정상빌드를 확인하였습니다.

하다보면 무슨 문제가 발생할지 모르겠지만 ^^

발견하는 대로 올리도록 하겠습니다.


모두들 iOS버전업으로 고생하시겠지만 힘내세요!




반응형
반응형

친한 지인분에게 티스토리 애드센스 신청이 안된다는 연락이 와서 

급하게 테스트 해보고 해결 방법 알려 드립니다. ^^


"URL에는 경로(예: example.com/경로) 또는 하위 도메인(하위도메인.example.com)이 포함될 수 없습니다. 자세히 알아보기"

라는 메시지가 나오는데 그럼 티스토리는 하위 도메인이라 안되는거야 ????


저도 테스트를 해봤는데 위와 같은 메시지가 나오면서 신청서 제출이 안되더군요...




그리고 이 문제에 대해 구글에세 제공하는 도큐멘트를 보면...

4번째 목로글 보시면 티스토리 도메인과 같은 형태 입니다. 

정말로 티스토리는 안되는건가??



하지만 다른 티스토리 블로그들을 보면 이미 애드센스 배너 광고를 하고 있는 블로그들이 많습니다.

그분들은 ?? 정책이 바뀐건가.. 라고 생각 하던 중 구글 애드센스 팀에 문의


"혹시 사용하시는 컴퓨터의 IP가 어떻게 되세요??"

IP를 알려주자.. 해외 거주자 세요?

"아니요"

"아이피 주소가 라오스로 나오고 있습니다." 


허허허 지금 사용 중인 인터넷이 콘텐츠 진흥원에서 공급받고 있는 IP인데 이 주소가 라오스라니....

그리고 한국 IP를 가지고 제 신청한 결과..


무사 통과!! 지인분들도 통과!! 


결론부터 말씀 드리면...

애드센스 팀에서 해준 얘기는 해외에서는 아직 티스토리와 같은 하위 도메인을 가진 주소는 안된다고 합니다.


해결 방법은

해외 거주자 분들은 한국에 계신 분들에게 아이디와 패스워드를 알려준 후 부탁드리는 방법과

아이디/패스워드 노출이 불안 하신 분들은 한국에 있는 컴퓨터에 원격 접속하여 신청서를 제출하는 방법


국내 거주자 분들 중 안되는 분들은 

http://ip60.kr/ 

에 접속하여 자신의 아이피와 위치를 확인 후 국내가 아니라면

국내 아이피를 사용하여 해보시길 바랍니다.


별거 아닌 문제 였는데...

아직 블로그 컨텐츠가 부족하여 애드센스 신청을 미루고 있지만(어차피 거절 당할거라 컨텐츠 부족으로 ^^)

이제 티스토리 안되는 건가.... 놀란 가슴 부여 잡고 글을 남깁니다. ^^


감사합니다.




반응형
반응형
게임한번하려는데 먼가 안돼서 설치하라고 해서 설치도 했는데 설치도 안되고 하면 
엄청 짜증날겁니다. 컴퓨터좀 하신다는 분들이야 간단하게 해결 하시는 분들도 있겠지만
컴터를 웹서핑과 게임만 다룰줄 안다면 갑갑하기 마련입니다.
주변 컴퓨터 좀 한다는 지인들에게 물어봐서 해결할 수 있지만 내가 아이유 같은 이쁜 여자가 
아니라면 곱게 알려주는 사람 별루 없을 겁니다 .

그래서 초보분들도 직접 해보시라고 포스팅 남겨 봅니다.

Visual c++ 2005 Redistributable 와 같은 프로그램을 설치 할 때 간혹 

“Command line option syntax error. Type command /? for Help” 와 같은
에러가 발생하면서 설치가 불가능 합니다.

이유부터 말씀 드리면 사용자 명이 한글로 되어 있을 때 발생합니다.
설치 시 temp폴더에 압축을 해제 후 설치를 하게 되는데 간혹 가다 한글 폴더명을 읽지 못하는 문제가 있습니다.

예를 들어 사용자명이 "아이유"로 되어 있을 경우 
"c:\Users\아이유\AppData\Local\Temp" 에 압축을 풀게 되죠.
아이유라는 한글 폴더 때문에 간혹 설치 문제가 발생하는 것 입니다.

해결방법을 알아 보겠습니다.
아이유라는 사용자 명을 영문으로 "아이유"에서 "iu" 라고 변경해 봐야 한번 사용자 폴더에 생성된 폴더는 변경되지 않습니다.
그렇다고 프로그램 하나를 설치하자고 사용자를 새로 영문으로 생성하여 하는 것은 시간도 낭비이고 
기존에 설치된 프로그램들을 재설치 해야 하는 문제도 발생할 수 있습니다.
이때 간단하게 문제를 해결 할 수 있는 방법이 있습니다.

바로 temp폴더를 변경하는 것 입니다. 
저도 같은 문제를 겪어 이것저것 해보았지만 이 방법이 젤 편하고 간단하였습니다.

temp폴더를 변경하는 방법은 아래와 같습니다.

"제어판 > 시스템 및 보안 > 시스템" 으로 이동 합니다.

고급 시스텝 설정을 클릭합니다.



환경 변수 버튼을 클릭 합니다.



환경변수에 빨간박스안에 있는 2개의 temp path를 위와 같이 변경해주면 설치가 가능합니다.



기존에 있던 값 들로 되돌리기 원하신다면 설치를 하시고 기존에 값을 메모장에 저장해 두었다가 

다시 되돌리면 됩니다.


lol설치 하던 친구가 설치가 안된다고 짜증을 내어 혹시나 같은 불편함을 겪고 있는 분들이 계실까 해서

간단하게 설치 하시라고 몇자 적어 보았습니다. ^^




반응형
반응형

2달전 cocos2d-x 사이트에서 sdkbox 라는걸 보고 흥미를 가지게 되었다.

유니티 애셋 스토어에서 많이들 팔고 있는 통합 플러그인을 cocos에서 

cocos2d-x용으로 만들고 있는 것이 였다.


cocos2d-x에서도 Plugin-X라는 것이 있긴 했지만 사용해 보지는 않았다.

(사용해보려고 했지만 그렇게 간편하지도 않고 Native로 개발하는 것과 큰차이 없어 보였음)


그런데 이번에 나온 sdkbox는 큰 매력이다. 

정말 단한줄로 iOS/Android 모두 사용 가능하다는 것과 기존에 콜백함수를 

각OS별로 따로 만들어 여러가지 방법으로(노티피케이션 등) Scene으로 

되돌려주는 코드도 만들어야 했다.


그런데 이번에 나온 sdkbox는 리스너까지 개발 되어 리스너 등록만 해주면 현재 Scene으로 

알아서 콜백 함수를 호출해 준다.


정말로 Android/iOS IAP가 통합된 기분 이랄까? 하루종일 걸릴꺼 1시간이면 하는 기분?


그 외에도 페이스북/방글/애널리틱스/애드콜로니 등등 여러가지 플러그인을 사용 가능하며

직접 문의한 결과 애드몹도 지원 예정에 있다고 한다.


점점 코코스에서 유니티를 따라잡기 위해 편의를 제공하는 것 같다.

현재 IAP와 애널리틱스, 페이스북까지 테스트를 완료 해봤으며 잘된다.

IAP에서 약간의 문제가 있었지만 지속적인 코코스 애들과 (짧디 짧은 영어로) 커뮤니케이션을

해서 많은 오류를 해결 했다.(첨엔 안드로이드 소모/비소모 아이템이 안되었음 ㅠㅠ)


시간 되는 대로 각 sdkbox에 사용 방법과 쉽게 사용하는 방법에 대해 포스팅하려고 한다.

(현재 한국에서 sdkbox를 아직 다루는 분이 없는것 같다 ㅠ ㅠ )


cocos2d-x sdkbox site

http://www.cocos2d-x.org/sdkbox

반응형
반응형

저는 개인적으로 for문을 사용할 때 ++i 를 사용 합니다.

신입시절 사수에게 이렇게 배웠고 아무 생각없이 코딩 스타일 이구나 생각 했습니다.


요즘 들어 궁금한 것이 많은 20대들이 자꾸 무슨 차이냐고 질문을 하길래

++i 써 그냥 했더니 점점 많은 것을 질문 하더군요 ^^


for문에서 ++i 와 i++ 의 가장큰 차이? 라고 하면 속도라고 할 수 있습니다.


C / C++ Code


1. ++i 의 경우


for( int i = 0; i < 10; ++i ) {

printf( "num: %d", i );

}


operator 코드

int int::operator++() {

this = this + 1;

return this;

}


2. i++ 의 경우

for( int i = 0; i < 10; i++ ) {

printf( "num: %d", i );

}


operator 코드
int int::operator++() {
int returnval = this;
i = i + 1;
return returnval;
}


operator코드를 보시면 둘의 차이점을 알 수 있습니다.

i++ 이 ++i 보다 한줄 더 많죠? 

임시 변수를 생성하기 때문에 그렇 습니다.


반면 ++i의 경우는 자신값에 바로 더해 리턴을 해주죠.

그래서 속도 측면에서 ++i가 더 빠르다고 볼 수 있는 거죠.


예전에야 하드웨어 성능 낮고 컴파일러도 최적화 되기 전에는 차이가 났겠지만

요즘 컴파일러도 최적화 되고 하드웨어 성능도 만만치 않은데 차이가 날까요 ? ^^


거의 없다고 보셔도 될겁니다. 


그냥 저는 코딩 스타일이라고 생각 합니다. 

아무거나 쓰셔도 무방 합니다!

반응형
반응형

Game Scene에 터치 리스너 붙이고 게임을 하다 Pause나 Shop같은 Layer를 띄웠을 경우 

Game Scene에 터치가 계속 먹어서 애를 먹은 적이 있다.


그래서 모달 레이어를 만드는 함수를 만들어 봤다.


cocos2d-x function


// 레이어(노드)를 모달로 만들어 주는 함수

void GameScene::modal_layer(cocos2d::Node *node)

{

    auto listener = EventListenerTouchOneByOne::create();

    listener->setSwallowTouches(true);

    listener->onTouchBegan = [](Touch *touch,Event*event)->bool {

        return true;

    };

    

    auto dispatcher = Director::getInstance()->getEventDispatcher();

    dispatcher->addEventListenerWithSceneGraphPriority(listener, node);

}


사용 예


auto modalLayer = Layer::create();

modal_layer( modalLayer ); 

this->addchild( modalLeyer );


Modal Layer 해제


this->removeChildmodalLayer );



GameScene에 멤버 함수로 넣어도 되고 모든 Scene에서 사용하겠다고 하면 static으로 만들던 Global함수로 만들던 상관 없다.

Layer를 remove시키면 Modal Layer 자동으로 해제 된다.

모달 레이어를 간단하게 사용할 수 있는 방법이다.


반응형
반응형

게임 개발을 하다보면 랜덤 함수는 거의 필수라 할 수 있다.

3Match 게임을 만들 때에도 랜덤으로 블록을 배치하기 위해 사용해야한다.

이 때 블록 타입을 랜덤으로 가져오는데 우연의 일치로 모든 랜덤 값이 동일하게 나온다면

모든 블록이 동일해지고 참으로 재미없는 일이 발생 할 것이다.


이러한 경우 원하는 블록타입을 하나씩 배치하기 위해서 중복없이 랜덤 값을 가져와야 한다.


C / C++ Function (shffle 라는 함수를 하나 만든다.)


void shuffle(int *data, int size)

{

    int temp = 0;

    for (int i = 0; i < size; ++i) {

        int randNum = getRandomNumber(0, size - 1);

        

        temp = data[randNum];

        data[randNum] = data[i];

        data[i] = temp;

    }

}


사용 예


// 10개의 블록 타입이 있다고 가정하고 0 ~ 9 까지 담고 있는 배열을 만든다.

#define MAX_BLOCK_TYPE 10

int arrayBlockNum[MAX_BLOCK_TYPE] = {0, };

for (int i = 0; i < MAX_BLOCK_TYPE; ++i) 

{

arrayBlockNum[i] = i + 1;

}


// 블록 타입을 담은 배열과 사이즈를 함수에 파라메터로 넘긴다.

shuffle(arrayBlockNum, MAX_BLOCK_TYPE);


위와 같이 해주면 배열안에 값들을 서로 바꿔주는 셔플 기능이기때문에 

0번째 배열부터 순차적으로 사용해도 배열안에 값들은 무엇이 나올지 모른다.


0~9번 배열까지 하나씩만 사용할 경우 중복 없이 랜덤 값을 가져올 수 있다.


1씩 증가하는 정수가 아니더라도 랜덤으로 뽑을 수를 배열에 넣고 셔플을 하면 

중복 없이 가져 올 수 있다. 


[주의]

셔플을 한다고 해도 0번 배열에 값을 여러번 사용 하면 중복 값이 되니 한번 사용한 배열의 값은 필요한 경우가 아니라면

사용하지말자!! ^^

반응형
반응형

게임을 개발하다 보면 정수를 정렬해야 할 때가 있습니다.

예를 들어 Best Score 같이 높은 수 부터 차례대로 보여 줘야 할 때 

정렬 해서 저장하는 것도 하나의 방법 이지만 불러 왔을 때 검수를 해야 할 때도 있습니다.


STL 라이브러리에 sort함수가 있어 이것을 이용해도 되지만 STL 사용 불가능 한 경우

(궁금하신 분들은 std::sort 검색 해보세요. ^^)


개인적으로 간단하게 정수 정도 오름/내림 차순으로 정렬을 해야 할 때는 아래 코드를 사용 합니다.


C / C++ Code


void insertion_sort(int *data, int size)

{

    int i, j, temp;

    

    for ( i = 1; i < size; ++i )

    {

        j = i;

        temp = data[j];

        

/*     

내림 차순 코드이며 오름 차순으로 할 경우

temp > data[j] 이 부분만 변경하시면 됩니다.

temp < data[j] 오름 차순 코드 입니다.

*/

        while ( --j >= 0 && temp > data[j] ) {

            data[j+1] = data[j];

        }

        

        data[j+1] = temp;

    }

}


사용방법


int array[3] = { 1, 3, 2 };

insertion_sort( array, 3 );


결과


for( int i = 0; i < 3; ++i ) {

printf("result: %d \n", array[i]);

}


출력


result: 3

result: 2

result: 1


간단하게 사용하는 삽입 정렬에 대해서 공유 해봤습니다.



반응형

+ Recent posts