[기초]Cocos2d-x 사건 처리 메커니즘

10376 단어 이벤트cocos2d-x
【성명】
본 논문 의 저작권 은 젤리 가 소유 하고 싶 습 니 다.전 재 를 환영 합 니 다.그러나 작가 의 동의 없 이 이 성명 을 보류 하고 글 페이지 의 뚜렷 한 위치 에서 원문 링크 를 제시 해 야 합 니 다.그렇지 않 으 면 법률 적 책임 을 추궁 할 권 리 를 보류 합 니 다.만약 이 문장 이 너 에 게 도움 이 된다 면,너 는 할 수 있다.
커피 한잔 주세요.
» 
본문 링크:http://www.jellythink.com/archives/769
» 
본 사이트 구독:http://www.jellythink.com/feed
» 
젤리 » 원본 링크:http://www.jellythink.com/archives/769
[본문]
이벤트 처리 메커니즘
Cocos2d-x v3.x 에서 사건 에 대한 처 리 는 Cocos2d-x v2.x 와 하늘 과 땅 차이 가 있 습 니 다.이 글 을 볼 때 Cocos2d-x v2.x 의 사건 처리 에 얽 매 이지 마 세 요.이 글 을 통 해 Cocos2d-x v3.x 의 사건 처리 기 제 를 정리 하 세 요.
하나의 이 벤트 는 트리거 에서 응답 완료 까지 다음 세 부분 으로 구성 되 어 있 습 니 다.
이벤트 배포 기 EventDispatcher;
사건 유형 EventTouch,EventKeyboard 등;
사건 감청 기 EventListenerTouch,EventListenerKeyboard 등.
Cocos2d-x v3.x 에서 사건 에 관 한 것 은 상기 세 부분 을 중심 으로 전개 되 었 을 뿐만 아니 라 상기 세 부분 을 파악 하면 Cocos2d-x v3.x 에서 사건 처리 의 정 수 를 파악 할 수 있다.
사건 분배 기:사건 분배 기 는 모든 사건 의'총 장관'에 해당 한다.모든 이벤트 모니터 를 관리 하고 관리 합 니 다.사건 이 발생 했 을 때 대응 하 는 사건 을 관리 하 는 것 을 책임 집 니 다.일반적으로 Director 클래스 중 getEventDispatcher 을 호출 하여 이벤트 스케줄 러 를 얻 고 게임 이 시 작 될 때 기본 EventDispatcher 대상 을 만 듭 니 다.
이벤트 유형:Cocos2d-x 에서 다음 과 같은 몇 가지 이벤트 유형 을 정의 합 니 다.
enum class Type
{
    TOUCH,          //     
    KEYBOARD,       //     
    ACCELERATION,   //      
    MOUSE,          //     
    FOCUS,          //     
    CUSTOM          //      
};

이벤트 감청 기:이벤트 감청 기 는 각종 이벤트 가 발생 한 후에 대응 하 는 논 리 를 실현 합 니 다.이벤트 분배 기 에서 대응 하 는 이벤트 감청 기 를 호출 합 니 다.Cocos2d-x 에서 다음 과 같은 이벤트 모니터 를 정의 합 니 다.
enum class Type
{
    UNKNOWN,            //         
    TOUCH_ONE_BY_ONE,   //          
    TOUCH_ALL_AT_ONCE,  //          
    KEYBOARD,           //        
    MOUSE,              //        
    ACCELERATION,       //         
    FOCUS,              //        
    CUSTOM              //         
};

다음은 상기 지식 점 에 대해 구체 적 인 코드 를 통 해 실천 한다.종이 위 에서 얻 은 것 은 결국 얕 게 느껴 져 서,이 일 을 몸소 해 야 한 다 는 것 을 절대 알 지 못 한다.
터치 이벤트
터치 사건 을 처리 할 때 다음 과 같은 두 가지 상황 이 있 습 니 다.
단일 터치 에 대해 서 는 이 네 가지 방법 을 다시 써 야 합 니 다.
onTouchBegan;
onTouchMoved;
onTouchEnded;
onTouchCancelled。

다 중 터치 에 대해 서 는 이 네 가지 방법 을 다시 써 야 합 니 다.
onTouchesBegan;
onTouchesMoved;
onTouchesEnded;
onTouchesCancelled。

물론 C++11 에 Lambda 라 는 것 도 잊 지 마 세 요.Lambda 표현 식 을 통 해 응답 논 리 를 직접 완성 할 수 있 습 니 다.C+에 Lambda 라 는 학생 에 대해 잘 모 르 겠 습 니 다.여 기 를 보 세 요.
터치 이벤트 에 어떻게 응답 하 는 지 코드 를 보 여 드 리 겠 습 니 다.
먼저 장면 에 세 개의 색 레이 어 를 추가 합 니 다.예제 코드 는 다음 과 같 습 니 다.
auto pLayer1 = LayerColor::create(Color4B::RED, 100, 100);
pLayer1->setPosition(Vec2(visibleSize.width / 2 - 100, visibleSize.height / 2 + 100));
addChild(pLayer1);

auto pLayer2 = LayerColor::create(Color4B::GREEN, 100, 100);
pLayer2->setPosition(Vec2(visibleSize.width / 2 - 60, visibleSize.height / 2 + 60));
addChild(pLayer2);

auto pLayer3 = LayerColor::create(Color4B::BLUE, 100, 100);
pLayer3->setPosition(Vec2(visibleSize.width / 2 - 20, visibleSize.height / 2 + 20));
addChild(pLayer3);

터치 이 벤트 를 추가 하 십시오.예제 코드 는 다음 과 같 습 니 다.
//             OneByOne     
auto listener1 = EventListenerTouchOneByOne::create();

//         , onTouchBegan    true   
listener1->setSwallowTouches(true);
listener1->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
listener1->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this);
listener1->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);

//      
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, pLayer1);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), pLayer2);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), pLayer3);

이벤트 처리 함 수 는 다음 과 같 습 니 다.
bool HelloWorld::onTouchBegan(Touch *touch, Event *unused_event)
{
    //          target 
    auto target = static_cast<Layer*>(unused_event->getCurrentTarget());
    if (target == nullptr)
    {
        return true;
    }

    //                   
    // getLocation    openGL   ,        
    Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation());
    Size s = target->getContentSize();
    Rect rect = Rect(0, 0, s.width, s.height);

    //         
    if (rect.containsPoint(locationInNode))
    {
        log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
        target->setOpacity(180);
        return true;
    }
    return false;
}

상기 코드 중_eventDispatcher
노드 의 속성 입 니 다.이 를 통 해 현재 노드(장면,층,요정 등)의 모든 이벤트 의 배 포 를 관리 합 니 다.그러나 그 자 체 는 단일 모드 값 의 참조 입 니 다.Node 의 구조 함수 에서 다음 코드 를 통 해 가 져 옵 니 다.
Director::getInstance()->getEventDispatcher();

이 속성 이 있 으 면 사건 을 편리 하 게 처리 하여 나 누 어 줄 수 있 습 니 다.
메모:listener 1 을 다시 사용 할 때 사용 해 야 합 니 다.clone()
사용 하고 있 기 때문에 새로운 복 제 를 만 드 는 방법addEventListenerWithSceneGraphPriority
혹은addEventListenerWithFixedPriority
방법 은 현재 사용 하고 있 는 이벤트 모니터 에 등 록 된 표 시 를 추가 하여 여러 번 등록 할 수 없습니다.또한,한 가지 중요 한 것 은 Fixed Priority listener 가 추 가 된 후 수 동 reove 가 필요 하 며,SceneGraph Priority listener 는 Node 와 연결 되 어 있 으 며,Node 의 석조 함수 에서 제 거 됩 니 다.
우 리 는 이미 추 가 된 감청 기 를 다음 과 같은 방법 으로 제거 할 수 있다.
_eventDispatcher->removeEventListener(listener);

현재 이벤트 배포 기 에 있 는 모든 모니터 를 제거 하 는 방법 도 다음 과 같다.
_eventDispatcher->removeAllEventListeners();

removeAll 을 사용 할 때 이 노드 의 모든 감청 이 제 거 됩 니 다.지정 한 삭제 방식 을 사용 하 는 것 을 추천 합 니 다.removeAll 이후 메뉴 도 응답 할 수 없습니다.터치 사건 도 받 아들 여야 하기 때문이다.
키보드 응답 이벤트
터치 이벤트 에서 사건 의 사용 에 대한 설명 이 비교적 상세 하고 다음 부분 은 코드 와 소량의 문자 만 을 통 해 이 사건 을 어떻게 사용 하 는 지 정리 합 니 다.
키보드 응답 이 벤트 를 실현 하려 면 다음 두 개의 가상 함 수 를 다시 써 야 합 니 다.
virtual void onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event);
virtual void onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event);

다음 과 같이 구현:
auto keyListener = EventListenerKeyboard::create();
keyListener->onKeyPressed = [](EventKeyboard::KeyCode keyCode, Event* event){ log("Key %d pressed.", keyCode);  };
keyListener->onKeyReleased = [](EventKeyboard::KeyCode keyCode, Event* event){ log("Key %d released.", keyCode); };

//      
_eventDispatcher->addEventListenerWithSceneGraphPriority(keyListener, this);

마우스 응답 이벤트
Cocos2d-x v 3.0 에 마우스 캡 처 이벤트 가 추가 되 었 습 니 다.이것 은 서로 다른 플랫폼 에서 우리 게임 의 사용자 체험 을 풍부 화 시 킬 수 있 습 니 다.오,다른 플랫폼,마우스 가 달 린 게임 플랫폼,PC 기기 요?코드 보 세 요.
auto mouseListener = EventListenerMouse::create();
mouseListener->onMouseDown = [](Event* event){ log("Mouse Down"); };
mouseListener->onMouseUp = [](Event* event){ log("Mouse Up"); };
mouseListener->onMouseMove = [](Event* event){ log("Mouse Move"); };
mouseListener->onMouseScroll = [](Event* event){ log("Mouse Scroll"); };

_eventDispatcher->addEventListenerWithSceneGraphPriority(mouseListener, this);

허 함 수 를 다시 쓰 는 방법 으로 는 완성 할 수 없 을 것 같 습 니 다.Lambda 표현 식 만 사용 할 수 있 습 니 다.기절 합 니 다.
액셀러레이터 이벤트
터치 외 에 모 바 일 기기 의 중요 한 입력 원 은 설비 의 방향 이기 때문에 대부분의 장 비 는 가속 계 를 설치 하여 설비 가 정지 하거나 등 속 운동 할 때 받 는 중력 방향 을 측정 하 는 데 사용 된다.
여러분 들 이 와 같은 파 쿠 게임 이 있 는 지 모 르 겠 습 니 다.핸드폰 이 왼쪽으로 이동 하거나 오른쪽으로 이동 하 는 것 을 제어 하면 게임 의 주인공 이 감지 할 수 있 습 니 다.그리고 왼쪽으로 뛰 거나 오른쪽으로 뛰 는 것 이 바로 모 바 일 기기 의 가속 기 를 바탕 으로 이 루어 진 것 입 니 다.
중력 감응 은 모 바 일 기기 의 가속 계 에서 나 오 는데 보통 X,Y,Z 세 방향의 가속도 감응 을 지원 하기 때문에 3 방향 가속 계 라 고도 부른다.실제 애플 리 케 이 션 에 서 는 휴대 전화의 기울어 진 각도 나 방향 을 3 개 방향의 강도 크기 에 따라 계산 할 수 있다.
Cocos2d-x 에서 가속기 에 관 한 코드 를 보 세 요.
class Acceleration
{
public:
    double x;
    double y;
    double z;

    double timestamp;

    Acceleration(): x(0), y(0), z(0), timestamp(0) {}
};

이 클래스 의 각 방향의 가속도 크기 는 중력 가속도 크기 이다.가속 이벤트 모니터 를 사용 하기 전에 다음 코드 를 사용 하여 이 하드웨어 장 치 를 먼저 사용 해 야 합 니 다.
Device::setAccelerometerEnabled(true);

그리고 대응 하 는 감청 기 를 만 듭 니 다.리 셋 함 수 를 만 들 때 Lambda 표현 식 으로 익명 함 수 를 만 들 수도 있 고 기 존 함수 논 리 를 연결 하여 실현 할 수도 있 습 니 다.다음 과 같 습 니 다.
auto listener = EventListenerAcceleration::create([=](Acceleration* acc, Event* event){
    //     
});
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

사용자 정의 이벤트
이상 은 시스템 자체 의 사건 입 니 다.시스템 자체 의 사건 이 당신 을 만족 시 키 지 못 하면 어떻게 합 니까?다행히 Cocos2d-x 에 서 는 배 고 픈 사용자 정의 이 벤트 를 제공 해'마음대로'할 수 있 게 해 준다.
시스템 이 벤트 는 터치 스크린,키보드 응답 등 시스템 내부 에서 자동 으로 발생 합 니 다.사용자 정의 이 벤트 는 시스템 이 자동 으로 촉발 하 는 것 이 아니 라 인위적인 간섭 이다.예제 코드 는 다음 과 같다.
//       JellyThinkCustomListener         
auto customListener = EventListenerCustom::create("JellyThinkCustomListener", [=](EventCustom* event)
{
    char* buf = static_cast<char*>(event->getUserData());
    pLabel2->setString(buf);
});

_eventDispatcher->addEventListenerWithSceneGraphPriority(customListener, this);

단 추 를 누 르 면 사용자 정의 이벤트 실행:
void HelloWorld::menuCloseCallback(Ref* pSender)
{
    static int count = 0;
    ++count;
    char *buf = new char[50];
    memset(buf, 0, 50);
    sprintf(buf, "http://www.jellythink.com +%d", count);

    EventCustom event("JellyThinkCustomListener");
    event.setUserData(buf);

    //        
    _eventDispatcher->dispatchEvent(&event);
    CC_SAFE_DELETE_ARRAY(buf);
}

효과 도 략.
보기 에는 매우 간단 한 것 같 습 니 다.네,사용 하기 가 이렇게 간단 합 니 다.이것 이 바로 Cocos2d-x 유행 하 는 이치 입 니 다.사용 하기 편 하고 하기 편 합 니 다.
총결산
또 한 걸음 을 내 디 뎠 다.이렇게 한 편의 총 결 을 내 려 가면 총 결 은 얻 을 수 있 을 것 이다.이 글 들 은 모두 비교적 기본 적 인 것 으로 Cocos2d-x 를 어떻게 사용 하 는 지,Cocos2d-x 소스 코드 에 대한 연 구 를 정리 한 다음 에 사용 한 다음 에 Cocos2d-x 의 소스 코드 를 연구 하기 시작 했다.
여기 서 전문 PDF 버 전 다운로드 제공:여 기 를 클릭 하여 다운로드

좋은 웹페이지 즐겨찾기