-
cocos2d-x 터치 및 스케쥴 정리Pause @/Cocos2d-x2 2013. 6. 29. 21:40
virtual void ccTouchesBegan(CCSet *touches, CCEvnet *event);
virtual void ccTouchesMoved(CCSet *touches, CCEvent *event);
virtual void ccTouchesEnded(CCSet *touches, CCEvent *event);
요렇게 3개의 virtual 메소드를 선언해줍니다.
이 메소드들은 CCLayer 객체에서 상속받은 메소드들로 터치에 관련된 처리를 가능하게 해줍니다. 이름만 봐도 딱 알겠죠? 터치가 시작되었을때, 이동했을때, 끝났을때 각각 호출이 됩니다. 복수형으로 되어 있죠? 멀티 터치를 지원하기 위한 것입니다. ^^
이전 버전에선 이 3가지가 왠일인지 리턴값과 파라메타가 조금씩 달랐던 것으로 기억이 나는데요. 지금은 3가지가 모두 똑같이 생겼죠? 내부적으로 코드도 똑같이 쓰면 됩니다.
근데 virtual 함수들을 선언하고 구현해도 왠일인지 터치에 반응을 안할텐데요 ^^;;
setTouchEnabled(true);
를 선언해 줘야 CCLayer가 touch에 반응하게 된다는점 잊지 마시기 바랍니다.
(init 메소드의 끝부분에 선언해 주면 됩니다.)
일단 현재 touch된 좌표값을 얻는 방법입니다.
CCTouch *touch = (CCTouch*)*touches->begin();
이렇게 받으면 들어온 멀티터치중 가장 첫번째 touch를 얻어 올수 있습니다.
딱보니깐 iterator 가 생각나시죠? 네.. 똑같은 방법으로 들어온 모든 멀티터치들을 순회하면서 얻어 올 수 있습니다.
하지만 우리는 첫번째 터치만 사용할겁니다. 이렇게 하면 싱글터치만 지원하는것과 똑같은 효과를 얻게 됩니다.
CCTouch 에서 현재 터치된 좌표를 얻는 방법은 다음과 같습니다.
CCPoint pt = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView());
touch->getLocationInView() 를 부르면 현재 view에서 터치된 좌표가 나옵니다.
근데 CCDirector::sharedDirector()->convertToGL()메소드에 한번더 태워서 변환해줍니다.
좌표계가 다르기 때문인데요.
cocos2d-x는 좌하단이 (0, 0) 우상단이 (width, height) 인 1사분면 좌표계를 사용합니다.
그런데 전통적인 touch 좌표계는 좌상단이 (0, 0) 우하단이 (width, height)인 4사분면 좌표계를 사용합니다. 그래서 convertToGL() 메소드를 사용해서 cocos2d-x가 사용하는 1사분면 좌표계로 변환을 해주면 더 직관적으로 사용이 가능합니다.
맴버변수로 CCPoint ptOrigin, ptCurrent; 를 선언해 주시구요.
ccTouchesBegan 에서 들어온 값은 ptOrigin, ptCurrent 양쪽에 모두 적용을 해줍니다.
그리고 ccTouchesMoved에서 들오온 값은 ptCurrent 에만 적용을 해줍니다.
ccTouchesEnded 에서는 양쪽 값을 임의의 값... 뭐 (0, 0) 같은걸로 초기화 해줘 버립니다.
대략 이런 모양새가 되겠죠?
void GameScene::ccTouchesBegan(CCSet *touches, CCEvent *event)
{
CCTouch *touch = (CCTouch*)*touches->begin();
ptOrigin = ptCurrent =
CCDirector::sharedDirector()->convertToGL(touch->getLocationInView());
}
void GameScene::ccTouchesMoved( ... )
{
...
ptOrigin = ptCurrent;
ptCurrent = CCDirector::sharedDirector()->convertToGL(touch->getLocationInView());
}
void GameScene::ccTouchesEnded(...)
{
...
ptOrigin = ptCurrent = ccp(0, 0);
}
이렇게 함으로서 현재 touch 값과 바로 이전 touch 값을 항상 저장할수 있게 되었습니다.
●스케줄
- 특정시간마다 특정함수를 호출한다.
- 정지(pause), 재시작(resume), 스테이지로 들어가면 타이머 활성화 등을 사용하게 해준다.
●예제
- HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
class HelloWorld : public cocos2d::CCLayerColor
{
public:
virtual bool init();
static cocos2d::CCScene* scene();
CREATE_FUNC(HelloWorld);
void doStart(CCObject* pSender);
void doPause(CCObject* pSender);
void doResume(CCObject* pSender);
void doChange(CCObject* pSender);
void doStop(CCObject* pSender);
void tick1(float f);
void tick2(float f);
int nNum;
bool bChange;
};
#endif // __HELLOWORLD_SCENE_H__
- HelloWorldScene.cpp
#include "HelloWorldScene.h"
using namespace cocos2d;
CCScene* HelloWorld::scene()
{
CCScene *scene = CCScene::create();
HelloWorld *layer = HelloWorld::create();
scene->addChild(layer);
return scene;
}
bool HelloWorld::init()
{
if ( !CCLayerColor::initWithColor(ccc4(255, 255, 255, 255)) )
{
return false;
}
/////////////////////////////
//메뉴아이템 생성
CCMenuItemFont* item1=CCMenuItemFont::create("start", this, menu_selector(HelloWorld::doStart));
item1->setColor(ccc3(0,0,0));
CCMenuItemFont* item2=CCMenuItemFont::create("pause", this, menu_selector(HelloWorld::doPause));
item2->setColor(ccc3(0,0,0));
CCMenuItemFont* item3=CCMenuItemFont::create("resume", this, menu_selector(HelloWorld::doResume));
item3->setColor(ccc3(0,0,0));
CCMenuItemFont* item4=CCMenuItemFont::create("change", this, menu_selector(HelloWorld::doChange));
item4->setColor(ccc3(0,0,0));
CCMenuItemFont* item5=CCMenuItemFont::create("stop", this, menu_selector(HelloWorld::doStop));
item5->setColor(ccc3(0,0,0));
//메뉴생성
CCMenu* pMenu=CCMenu::create(item1, item2, item3, item4, item5, NULL);
pMenu->alignItemsVertically();
this->addChild(pMenu);
//변수초기화
nNum=0;
bChange=false;
return true;
}
void HelloWorld::doStart(CCObject* pSender)
{
this->schedule(schedule_selector(HelloWorld::tick1), 1.0f);
this->schedule(schedule_selector(HelloWorld::tick2), 2.0f);
}
void HelloWorld::doPause(CCObject* pSender)
{
CCDirector::sharedDirector()->getScheduler()->pauseTarget(this);
}
void HelloWorld::doResume(CCObject* pSender)
{
CCDirector::sharedDirector()->getScheduler()->resumeTarget(this);
}
void HelloWorld::doChange(CCObject* pSender)
{
if(bChange){
bChange=false;
this->unschedule(schedule_selector(HelloWorld::tick2));
this->schedule(schedule_selector(HelloWorld::tick2), 2.0f);
}else{
bChange=true;
this->unschedule(schedule_selector(HelloWorld::tick2));
this->schedule(schedule_selector(HelloWorld::tick2),3.0f);
}
}
void HelloWorld::doStop(CCObject* pSender)
{
this->unschedule(schedule_selector(HelloWorld::tick1));
this->unschedule(schedule_selector(HelloWorld::tick2));
}
void HelloWorld::tick1(float f) //스케줄로 호출하는 함수는 인자로 float를 가져야한다.
{
CCLog("tick1");
}
void HelloWorld::tick2(float f)
{
CCLog("tick2");
}
●Scene내의 모든 액션과 스케줄을 정지, 재시작
- CCDirector::sharedDirector()->paruse()
- CCDirector::sharedDirector()->resume()
'Pause @ > Cocos2d-x2' 카테고리의 다른 글
cocos2d-x transition, parallaxnode (0) 2013.06.30 cocos2d-x 스케쥴update, CCSpriteBatchNode (0) 2013.06.30 cocos2d-x animation 정리 (0) 2013.06.30 cocos2d-x 정리 2일차 (0) 2013.06.24 cocos2d-x 정리.. (0) 2013.06.23