1. 程式人生 > >cocos2d-x學習筆記——EventDispatcher事件分發機制

cocos2d-x學習筆記——EventDispatcher事件分發機制

EventDispatcher 事件分發機制先建立事件,註冊到事件管理中心 _eventDispatcher,通過釋出事件得到響應進行回撥,完成事件流。_eventDispatcher是Node的屬性,通過它管理當前節點(場景、層、精靈等)的所有事件的分發。但它本身是一個單例模式值的引用,在Node的建構函式中,通過Director::getInstance()->getEventDispatcher(); 獲取,有了這個屬性,就能方便的處理事件。

有五種不同的事件機制:

  1. EventListenerTouch 響應觸控事件
  2. EventListenerKeyboard 響應鍵盤事件
  3. EventListenerAcceleration 響應加速器事件
  4. EventListenMouse 響應滑鼠事件
  5. EventListenerCustom 響應自定義的事件

優先順序:

  1. addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority) 中 fixedPriority 的值越低,則優先順序越高。
  2. 若優先順序相同。Layer 的z順序高的(繪製於頂部的)層將優於z順序低的層。這將保證了諸如觸碰事件的自頂向下傳播

  3. 注意:如果是固定優先值的監聽器新增到一個節點(addEventListenerWithFixedPriority),那當這個節點被移除時必須同時手動移除這個監聽器,但是新增場景圖優先監聽器到節點(addEventListenerWithSceneGraphPriority)就不用這麼麻煩,監聽器和節點是繫結好的,一旦節點的解構函式被呼叫,監聽器也會同時被移除。

觸控事件:

void EventDispatcherTest::funEventTouch(Sprite* sprite)
{
    this->_eventDispatcher->removeAllEventListeners();

    auto listener = EventListenerTouchOneByOne::create();
    listener->onTouchBegan = CC_CALLBACK_2(EventDispatcherTest::onTouchBeganss,this);
    listener->onTouchMoved = CC_CALLBACK_2(EventDispatcherTest::onTouchMovedss,this
); listener->onTouchEnded = CC_CALLBACK_2(EventDispatcherTest::onTouchEndedss,this); listener->onTouchCancelled = CC_CALLBACK_2(EventDispatcherTest::onTouchCancelledss,this); listener->setSwallowTouches(true);//是否向下傳遞 this->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,sprite); } bool EventDispatcherTest::onTouchBeganss(Touch* touch,Event* ev) { auto target = static_cast<Sprite*>(ev->getCurrentTarget()); Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation()); Size s = target->getContentSize(); Rect rect = Rect(0, 0, s.width, s.height);   //判斷觸控區域是否在目標上 if (rect.containsPoint(locationInNode)) { label->setString("onTouchBegan......"); target->setOpacity(180); return true; } return false; } void EventDispatcherTest::onTouchMovedss(Touch* touch,Event* ev) { auto target = static_cast<Sprite*>(ev->getCurrentTarget()); target->setPosition(target->getPosition() + touch->getDelta()); label->setString("onTouchMoved......"); } void EventDispatcherTest::onTouchEndedss(Touch* touch,Event* ev) { auto target = static_cast<Sprite*>(ev->getCurrentTarget()); target->setOpacity(255); label->setString("onTouchEnded......"); } void EventDispatcherTest::onTouchCancelledss(Touch* touch,Event* ev) { label->setString("onTouchCancelled......"); }

鍵盤事件:

void EventDispatcherTest::funEventKeyboard()
{
    this->_eventDispatcher->removeAllEventListeners();

    auto listener = EventListenerKeyboard::create();
    listener->onKeyPressed = CC_CALLBACK_2(EventDispatcherTest::onKeyPressedss,this);
    listener->onKeyReleased = CC_CALLBACK_2(EventDispatcherTest::onKeyReleasedss,this);
    this->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
}

void EventDispatcherTest::onKeyPressedss(EventKeyboard::KeyCode keycode,Event* ev)
{
    char txt[100] = {};
    sprintf_s(txt,"key %d is Pressed!",(int)keycode);
    label->setString(txt);
}

void EventDispatcherTest::onKeyReleasedss(EventKeyboard::KeyCode keycode,Event* ev)
{
    label->setString("key is Released!");
}

滑鼠事件:

void EventDispatcherTest::funEventMouse(Sprite* sprite)
{
    this->_eventDispatcher->removeAllEventListeners();

    auto listener = EventListenerMouse::create();
    listener->onMouseDown = CC_CALLBACK_1(EventDispatcherTest::onMouseDownss,this);
    listener->onMouseMove = CC_CALLBACK_1(EventDispatcherTest::onMouseMovess,this);
    listener->onMouseUp = CC_CALLBACK_1(EventDispatcherTest::onMouseUpss,this);
    listener->onMouseScroll = CC_CALLBACK_1(EventDispatcherTest::onMouseScrollss,this);
    this->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,sprite);
}

void EventDispatcherTest::onMouseDownss(Event* ev)
{
    label->setString("onMouseDown!");
}
void EventDispatcherTest::onMouseMovess(Event* ev)
{
    label->setString("onMouseMove!");
}
void EventDispatcherTest::onMouseUpss(Event* ev)
{
    label->setString("onMouseUp!");
}
void EventDispatcherTest::onMouseScrollss(Event* ev)
{
    label->setString("onMouseScroll!");
}

自定義事件:

//自定義事件
funEventCustom();
//2秒發派一次自定義事件,測試
scheduleOnce(schedule_selector(EventDispatcherTest::dispatcherCustomEvents),2.0f);

void EventDispatcherTest::funEventCustom()
{
    auto listener = EventListenerCustom::create("custom_event_1",CC_CALLBACK_1(EventDispatcherTest::onEventCustom,this));
    this->_eventDispatcher->addEventListenerWithFixedPriority(listener,1);//新增到事件分發器
}

void EventDispatcherTest::dispatcherCustomEvents(float at)
{
    //派發事件custom_event_1  事件內容為字串custom event test!
    this->_eventDispatcher->dispatchCustomEvent("custom_event_1","custom event test!");
}

void EventDispatcherTest::onEventCustom(EventCustom* event)
{
    auto data = static_cast<char*>(event->getUserData());
    label->setString(data);
}

加速器事件:

 除了觸控,移動裝置上一個很重要的輸入源是裝置的方向,因此大多數裝置都配備了加速計,用於測量裝置靜止或勻速運動時所受到的重力方向。

重力感應來自移動裝置的加速計,通常支援X,Y和Z三個方向的加速度感應,所以又稱為三向加速計。在實際應用中,可以根據3個方向的力度大小來計算手機傾斜的角度或方向。

加速計監聽器EventListenerAcceleration,其靜態create方法中有個Acceleration的引數。Acceleration是一個類,包含了加速計獲得的3個方向的加速度。

void EventDispatcherTest::funEventAcceleration()
{
    //啟動硬體裝置
    Device::setAccelerometerEnabled(true); 

    auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(EventDispatcherTest::onAcceleration,this));
    this->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
}

void EventDispatcherTest::onAcceleration(Acceleration* acc,Event* event)
{
    char str[100]={};
    sprintf_s(str,"x:%2d,y:%2d,z:%2d,timestamp:%2d",acc->x,acc->y,acc->z,acc->timestamp);
    log(str);
}

相關推薦

cocos2d-x學習筆記——EventDispatcher事件分發機制

EventDispatcher 事件分發機制先建立事件,註冊到事件管理中心 _eventDispatcher,通過釋出事件得到響應進行回撥,完成事件流。_eventDispatcher是Node的屬性,通過它管理當前節點(場景、層、精靈等)的所有事件的分發。但它

cocos2d-x學習筆記(c++與lua交互回調函數的處理)

回調函數 tolua++ cocos2dx lua 本文假設讀者已經會使用tolua++進行C++與lua之間的通訊1、在頭文件中定義註冊回調函數,定義在MyClass類中void register(unsigned short cmdID, LUA_FUNCTION func);//LUA_

Cocos2d-x學習筆記(四) 布景層的加入移除

dcl from position 顏色 顯示地圖 idt col 分享 學習 布景層類也就是CCLayer類,每一個遊戲場景中都能夠有非常多層,每一層負責各自的任務。顯示地圖、顯示人物等。同一時候層還是一個容器,能夠放入文本、圖片和菜單。構成遊戲中一個個UI。這次

cocos2d-x學習筆記(十二)cocos2dx 3.10添加lua LuaFileSystem庫遍歷文件

luafilesystem庫;lfs;遍歷文件在lua中遍歷目錄文件需要用到lfs庫,而所用的cocos2dx 3.10沒用lfs,需要自己添加1、下載lfs.c和lfs.hhttps://github.com/keplerproject/luafilesystem 從github獲取源碼,在src目錄拷貝l

從另一個思路來學習安卓事件分發機制

從另一個思路來學習安卓事件分發機制 前言 事件分發機制是一個安卓老生常談的話題了,從前幾年的面試必問題到如今的本當成預設都會的基礎知識。關於這方面的部落格網上已經有很多很多了,有從原始碼分析的,有從實際出發開始分析的等等。面對這麼多的教程,小白可能一頭霧水不知道從哪裡看起,而且看完之後感覺啥也沒留下。那麼

Cocos2d-x學習筆記(十)例項——記住帳號(密碼)功能

【關於記住賬號/密碼】 在很多需要賬號、密碼驗證的應用程式,“記住密碼”是非常常見的,那麼如何用cocos2d-x來實現呢?這裡用選單來實現“記住密碼”的功能。 【記住賬號/密碼的實現】 (1)首先準備兩張圖片,即選單項兩種狀態(正常和點選)下顯示的的圖片背景,以便在使用者多次

Cocos2d-x學習筆記(九)例項——場景自動切換

【關於場景自動切換】 如何實現場景的自動切換?我嘗試過很多種方法,比如在AppDelegate.cpp檔案中的applicationDidFinishLaunching()函式中, 想在pDirector->runWithScene(pLandlords);中直接使用replace

Cocos2d-x學習筆記(八)例項——精靈Action

【關於精靈Action】 精靈的動作分為瞬時動作和延時動作,瞬時動作中間不產生任何動畫效果,而延時動作則會產生很多的動畫效果。動畫效果主要還是要靠延時動作類CCActionInterval的子類來實現,其應用例項在TestCpp裡面有很多的例子。 單純的實現一個精靈動作很簡單,只要

Cocos2d-x學習筆記(七)例項——繪製圖形

【關於draw函式】 在節點類CCNode中,可以重寫draw函式並在其中繪製圖形。Draw是一個虛擬函式,只要繼承CCNode的子類都可使用,只要在其函式內部新增繪圖操作即可在場景中顯示繪製的圖形。 【1】為了使繪製的圖形更清晰,將init()裡所有關於佈景的資源(

Cocos2d-x學習筆記(六)例項——多層佈景

【關於多層佈景】 在遊戲開發中,一般會把遊戲分為兩部分:一部分是遊戲介面部分,也就是常說得UI部分;另一部分就是遊戲本身部分。有時UI有很多頁面,在頁面中用的圖也不是很多,不需要進行場景切換,只需把不同頁面做成不同的佈景,然後切換佈景層。那麼就需要一個“管理者”來管理這些介面,這時

Cocos2d-x學習筆記(五)例項——場景切換

【1】首先設計場景需要許多的圖片資源,往resource資料夾裡新增資原始檔: 【2】新建Cocos2d-x工程時預設的是HelloWord場景,在此只做先顯示佈景層中相關精靈圖片以及選單圖片的修改: 【3】在剛剛的init()函式中有兩個選單回撥函式,主要

Cocos2d-x學習筆記(四)淺析動作類CCAction(3)

【1】動作管理類CCActionManager: 動作管理類CCActionManager是一個管理所有動作的單例,可以對動作進行一系列的操作,如:新增動作、刪除動作、暫停動作、重啟動作,這個單例可以通過CCDirector::sharedDirector()->getActionMa

Cocos2d-x學習筆記(三)淺析動作類CCAction(2)

有關CCAction其它動作類簡介: (1)攝像機動作類CCOrbitCamera:  攝像機動作是環繞中心螢幕旋轉所形成的動作,其旋轉座標採用球座標描述。  Create()函式原型CCOrbitCamera* create(fl

Cocos2d-x學習筆記(二)淺析動作類CCAction(1)

Cocos2d-x的動作類CCAction並不是一個在螢幕中顯示的物件,動作必須要依託於CCNode類及其子類的例項才能發揮作用。CCAction繼承於物件類CCObject,有三個子類:有限時間動作、跟隨、移動速度,其中有限時間動作子類CCActionInterVal會形成動畫過程。

Cocos2d-x學習筆記(一)HelloCpp的來龍去脈

【1】首先分析HelloCpp專案的檔案結構,分為Classes、win32、外部檔案依賴三個資料夾,其中外部依賴資料夾暫且不用理會。 Classes主要包含像導演、場景、佈景、攝像機、精靈、App相關類的申明和定義; Win32主要是應用程式框架的WinMain函式入口(包

筆記事件分發機制(二):ViewGroup的事件分發

前言 前面我根據郭大神的部落格做了View的事件分發的筆記 筆記:事件分發機制(一):View的事件分發 對View的事件分發有了一個比較深入的瞭解。 本篇還是就郭大神的部落格 Android事件分發機制完全解析,帶你從原始碼的角度徹底理解(下)

cocos2d-x學習筆記——cocos2d-x3.0回撥函式的變化

在cocos2d-x 2.x版本中的回撥函式的用法想必大家都很是熟悉,例如在menu item,call back action中都需要大量的使用到回撥函式,但是在使用過程中總是感覺到比較冗餘麻煩的,在3.0版本,使用到了C++11 的新特性,改進增加了回

cocos2d-x學習筆記-CCMenu和CCMenuItem詳解

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

cocos2d-x學習筆記(10)重複動作RepeatForever和Repeat 以及動作組合Sequence和Spawn

Repeat和RepeatForever Sprite* sprite=Sprite::create("sprite.png"); sprite->setPosition(Point(visibleSize.width/2,visibleSize.height/

Cocos2d-x學習筆記(三)CCNode分析

class CC_DLL CCNode : public CCObject { public: CCNode(void); virtual ~CCNode(void); // 初始化節點 virtual bool init(); // 建立一個節點物