원글 출처 : http://horns.tistory.com/19
1. CCProgressTimer
HelloWorldScene.h
class HelloWorld : public cocos2d::Layer { private: ... CCProgressTimer* _progressTimeBar; ... }
HelloWorldScene.cpp
void HelloWorld::createGameScene() { ... //타임 바 추가 Sprite* timeOutline = Sprite::create("timebar.png"); timeOutline->setPosition(ccp(_screenSize.width * 0.5f, 27)); timeOutline->setColor(Color3B::GRAY); timeOutline->setScaleX(_screenSize.width / timeOutline->getContentSize().width); timeOutline->setVisible(true); this->addChild(timeOutline); Sprite* timerBar = Sprite::create("timebar.png"); _progressTimeBar = ProgressTimer::create(timerBar); _progressTimeBar->setPosition(ccp(_screenSize.width * 0.5f, 27)); _progressTimeBar->setScale(_screenSize.width / timerBar->getContentSize().width); _progressTimeBar->setPercentage(100.0f); _progressTimeBar->setMidpoint(ccp(0, 0.5f)); _progressTimeBar->setBarChangeRate(ccp(1, 0)); _progressTimeBar->setType(kCCProgressTimerTypeBar); this->addChild(_progressTimeBar); ProgressFromTo* progressFromToZero = ProgressFromTo::create(60, 100, 0); _progressTimeBar->runAction(progressFromToZero); initGameCoin(); }
원래는 timerbar와 timeroutline을 각각 다른 이미지로 사용하였는데, 제가 사용하는 태블릿 화면 해상도와 맞지 않아서 그런지 정확히 위치를 맞추기 어렵더군요. 그래서 둘 다 같은 이미지로 사용하는 대신 밑에 깔린 막대바 색을 회색으로 덮어씌워서 게이지가 줄어드는걸 표현했습니다. 하시는 분 중에는 노란색 게이지바 크기를 좀 더 작게 한다던가 해서 테두리를 표현할 수도 있을거같네요.
검색해보니 cocos2d-x 2.x버전대에서는 createWithSpriteStroke라고 sprite에 테두리를 주는 메서드가 존재했었던것도 같은데..여튼 3.2버전에서는 관련 내용이 전혀 없는 느낌이므로 굳이 방법을 찾지 않고 두도록 하겠습니다.
HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "GameCoin.h" #include "OpeningScene.h" using namespace cocos2d; using namespace std; class HelloWorld : public cocos2d::Layer { private: ... CCProgressTimer* _progressTimeBar; int _gameTime; public: ... void timeCount(float dt); void changeToOpeningScene(); };
HelloWorldScene.cpp
void HelloWorld::initGameCoin() { int coinX = 0; int coinY = 0; int diffX = _screenSize.width * 0.135f; //코인 x 간격 int diffY = _screenSize.height * 0.097f; //코인 y 간격 int initCoinX = _screenSize.width * 0.095f; //초기 코인 x 위치 int initCoinY = _screenSize.height * 0.613f; //초기 코인 y 위치 GameCoin* gameCoin; _lastCoin = -1; _selectCoinCount = 0; _score = 0; _gameTime = 60; ... }
void HelloWorld::timeCount(float dt){ if(--_gameTime == 0){ changeToOpeningScene(); } } void HelloWorld::changeToOpeningScene(){ this->unschedule(schedule_selector(HelloWorld::timeCount)); Scene* pScene = Opening::scene(); TransitionScene* pTran = TransitionFade::create(0.5f, pScene); Director::getInstance()->replaceScene(pTran); }
bool HelloWorld::init() { ////////////////////////////// // 1. super init first if (!Layer::init()) { return false; } _screenSize = Director::sharedDirector()->getWinSize(); this->setTouchEnabled(true); this->schedule(schedule_selector(HelloWorld::timeCount),1.0f); ... }
주의해야할건, schedule은 호출하는 함수에 float값을 넘겨주기 때문에 호출 받는 함수가 float 형의 변수를 가져야 합니다. 만약 timeCount 함수를 timeCount(){ } 로 작성했다면 에러가 납니다. 따라서 호출 받는 함수 내에 시간 관련 동작이 없더라도 반드시 float 변수를 만들어놔야만 동작합니다.
덧붙여 timeCount()에서 (--_gameTime == 0)의 --는 저도 얼른 이해가 안되네요ㅠㅠ;
일단 저기서 --를 떼고 실행하면 타이머가 0이 되어도 게임이 제대로 종료 되지 않습니다.
실행 결과 :
시간이 다되면 다시 OpeningScene로 넘어갑니다.
Horns님이 올리신 강좌를 따라 여기까지 했습니다. 정말 마이그레이션이라고 하기도 뭐하고, 순전히 기존 소스를 3.2에서도 동작하도록 고친것 뿐이라서, 실제 소스 효율이나 이런저런것에 대해선 잘 모릅니다. (Vec2같이 새로 생긴 애들..)
기존에 올린 강좌 그대로 따라하면서 했기 때문에 여기까진 빠른 시간 내에 마칠 수 있었네요.
이 다음부터는 개인적으로 커스텀해서 게임에 요소를 추가할지, 혹은 이 소스를 응용해서 새로 게임을 만들지 고민되네요.
일단 계속 진행한다면, 기기 해상도별로 대응 가능하도록 하기, 코인별로 점수를 다르게 하기, 점수를 획득하면 시간이 좀 더 늘어나도록 하기, 같은 코인 내에서 움직였다가 다시 후퇴해서 움직이면 선택했던 코인이 취소되기 등등..이것저것 추가해보도록 할 것 같습니다...만 이런식으로 소스를 마구 건드리는게 원래 강좌를 올린 Horns님에 대한 예의도 아닌것같고ㅠㅠ 제가 어디까지 성공할 수 있을지도 걱정이고 이래저래 고민이 많네요.
여튼 포코팡 비슷한 게임 만들기 여기서 일단 마무리 짓겠습니다. 겨우 보름남짓이었는데 정말 온갖 에러와 사이좋게 놀았네요--;..
강좌를 이용해서 포스팅 할 수 있도록 허락해주신 Horns님께 다시 한 번 감사드립니다!