cocos2d-x 공부용2014. 9. 17. 18:07

원글 출처 : 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님께 다시 한 번 감사드립니다!

Posted by 아이시네프