欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

cocos2dx觸屏事件詳解 - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設(shè)-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設(shè)/小程序開發(fā)/軟件開發(fā)

知識

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏壧峁┍憬莸闹С郑?

您當(dāng)前位置>首頁 » 新聞資訊 » 技術(shù)分享 >

cocos2dx觸屏事件詳解

發(fā)表時間:2020-10-19

發(fā)布人:葵宇科技

瀏覽次數(shù):85


版本:2.x
平臺iso
先看mian.m文件
//創(chuàng)建一個iso應(yīng)用
int retVal = UIApplicationMain(argc, argv, nil, @"AppController");
iOS體系會調(diào)用AppController 的 didFinishLaunchingWithOptions函數(shù),瑯綾擎做了一些創(chuàng)建界面的器械
該函數(shù)內(nèi)部有如下代碼;
cocos2d::CCApplication::sharedApplication()->run();
注:*.mm文件為object C與C++混編文件定名
AppController.mm文件膳綾擎對 AppDelegate創(chuàng)建一個對象,AppDelegate持續(xù)于CCApplication, cocos2d::CCApplication::sharedApplication()取得的就是該對象

static AppDelegate s_sharedApplication;
進(jìn)入 CCApplication::run()函數(shù)
int CCApplication::run()
{
    if (applicationDidFinishLaunching()) 
    {
        [[CCDirectorCaller sharedDirectorCaller] startMainLoop];
    }
    return 0;
}
進(jìn)入AppDelegate::applicationDidFinishLaunching 函數(shù),省略部分代碼
bool AppDelegate::applicationDidFinishLaunching()
{
    // initialize director
    CCDirector *pDirector = CCDirector::sharedDirector();
    pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
進(jìn)入setOpenGLView函數(shù),
void CCDirector::setOpenGLView(CCEGLView *pobOpenGLView)
{
。
。
。
        m_pobOpenGLView->setTouchDelegate(m_pTouchDispatcher);//設(shè)置觸摸代勞 只是對CCEGLViewProtocol中 EGLTouchDelegate* m_pDelegate; 變量初始化
        m_pTouchDispatcher->setDispatchEvents(true);//設(shè)置接收派發(fā)事宜
    }
}
CCDirector::init() 已經(jīng)對cocos2dx引擎用到的變量進(jìn)行了一些初始化
 m_pTouchDispatcher = new CCTouchDispatcher();
  m_pTouchDispatcher->init();
我們先回頭看一下cocosdx是怎么大年夜ios體系中取得觸摸事宜:
為了便于針對openGL ES的編程,蘋不雅公司供給了派生于類UIView的類EAGLView來實(shí)現(xiàn)OpenGL的輸出支撐。
如許EAGLView.mm中得
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
就會接收到ios體系發(fā)送過來的觸屏事宜
瑯綾擎分別調(diào)用了
cocos2d::CCEGLView::sharedOpenGLView()->handleTouchesBegin(i, ids, xs, ys);
cocos2d::CCEGLView::sharedOpenGLView()->handleTouchesMove(i, ids, xs, ys);
cocos2d::CCEGLView::sharedOpenGLView()->handleTouchesEnd(i, ids, xs, ys);
cocos2d::CCEGLView::sharedOpenGLView()->handleTouchesCancel(i, ids, xs, ys);
進(jìn)入CCEGLViewProtocol 的┞封幾個函數(shù),瑯綾擎分別調(diào)用了
m_pDelegate->touchesBegan(&set, NULL);
m_pDelegate->touchesMoved(&set, NULL);
m_pDelegate->touchesEnded(&set, NULL);
m_pDelegate->touchesCancelled(&set, NULL);
膳綾擎已經(jīng)對m_pDelegate 進(jìn)行了賦值 
m_pTouchDispatcher = new CCTouchDispatcher();
 m_pobOpenGLView->setTouchDelegate(m_pTouchDispatcher);
如許CCTouchDispatcher 就能接收到ios體系發(fā)送過來的觸屏事宜了。
看一下 這幾個函數(shù) m_bDispatchEvents 膳綾擎已經(jīng)對其設(shè)置為 true 然后這幾個函數(shù)都邑調(diào)用該類的touches函數(shù)
void CCTouchDispatcher::touchesBegan(CCSet *touches, CCEvent *pEvent)
{
    if (m_bDispatchEvents)
    {
        this->touches(touches, pEvent, CCTOUCHBEGAN);
    }
}
void CCTouchDispatcher::touchesMoved(CCSet *touches, CCEvent *pEvent)
{
    if (m_bDispatchEvents)
    {
        this->touches(touches, pEvent, CCTOUCHMOVED);
    }
}
void CCTouchDispatcher::touchesEnded(CCSet *touches, CCEvent *pEvent)
{
    if (m_bDispatchEvents)
    {
        this->touches(touches, pEvent, CCTOUCHENDED);
    }
}
void CCTouchDispatcher::touchesCancelled(CCSet *touches, CCEvent *pEvent)
{
    if (m_bDispatchEvents)
    {
        this->touches(touches, pEvent, CCTOUCHCANCELLED);
    }
}
我們來看下touches函數(shù)
void CCTouchDispatcher::touches(CCSet *pTouches, CCEvent *pEvent, unsigned int uIndex)
{
    CCAssert(uIndex >= 0 && uIndex < 4, "");
    CCSet *pMutableTouches;
    m_bLocked = true;
    // optimization to prevent a mutable copy when it is not necessary
     unsigned int uTargetedHandlersCount = m_pTargetedHandlers->count();
     unsigned int uStandardHandlersCount = m_pStandardHandlers->count();
    bool bNeedsMutableSet = (uTargetedHandlersCount && uStandardHandlersCount);
    pMutableTouches = (bNeedsMutableSet ? pTouches->mutableCopy() : pTouches);
    struct ccTouchHandlerHelperData sHelper = m_sHandlerHelperData[uIndex];
    //
    // process the target handlers 1st
    //單點(diǎn)觸摸
    if (uTargetedHandlersCount > 0)
    {
        CCTouch *pTouch;
        CCSetIterator setIter;
        for (setIter = pTouches->begin(); setIter != pTouches->end(); ++setIter)
        {
            pTouch = (CCTouch *)(*setIter);
            CCTargetedTouchHandler *pHandler = NULL;
            CCObject* pObj = NULL;
  //大年夜CCTargetedTouchHandler的數(shù)組中掏出單個CCTargetedTouchHandler對象
            CCARRAY_FOREACH(m_pTargetedHandlers, pObj)
            {
                pHandler = (CCTargetedTouchHandler *)(pObj);
                if (! pHandler)
                {
                   break;
                }
                bool bClaimed = false;
                if (uIndex == CCTOUCHBEGAN)
                {
//這里調(diào)用CCTargetedTouchHandler對象的ccTouchBegin辦法,我們知道cocos2dx中l(wèi)ayer為cocos2dx中接收觸屏事宜的最小單位
                    bClaimed = pHandler->getDelegate()->ccTouchBegan(pTouch, pEvent);
//如不雅ccTouchBegin 辦法返回true 會把這個CCTargetedTouchHandler對象 參加到 處理 move end canceled 的數(shù)組中
//意思就是 如不雅ccTouchBegin 辦法返回true  該CCTargetedTouchHandler對象  才會持續(xù)接收到 move end canceled 這三個事宜
                    if (bClaimed)
                    {
                        pHandler->getClaimedTouches()->addObject(pTouch);
                    }
                } else
                if (pHandler->getClaimedTouches()->containsObject(pTouch))
                {
                    // moved ended canceled
                    bClaimed = true;
                    switch (sHelper.m_type)
                    {
                    case CCTOUCHMOVED:
                        pHandler->getDelegate()->ccTouchMoved(pTouch, pEvent);
                        break;
                    case CCTOUCHENDED:
                        pHandler->getDelegate()->ccTouchEnded(pTouch, pEvent);
                        pHandler->getClaimedTouches()->removeObject(pTouch);
                        break;
                    case CCTOUCHCANCELLED:
                        pHandler->getDelegate()->ccTouchCancelled(pTouch, pEvent);
                        pHandler->getClaimedTouches()->removeObject(pTouch);
                        break;
                    }
                }
//如不雅有CCTargetedTouchHandler對象  接收到這個觸摸事宜了 如不雅設(shè)置為兼并事宜 不向下傳遞了 這里就會把 觸屏事宜刪除
                if (bClaimed && pHandler->isSwallowsTouches())
                {
                    if (bNeedsMutableSet)
                    {
                        pMutableTouches->removeObject(pTouch);
                    }
                    break;
                }
            }
        }
    }
    //
    // process standard handlers 2nd
    //這里是多點(diǎn)觸摸
    if (uStandardHandlersCount > 0 && pMutableTouches->count() > 0)
    {
        CCStandardTouchHandler *pHandler = NULL;
        CCObject* pObj = NULL;
        CCARRAY_FOREACH(m_pStandardHandlers, pObj)
        {
            pHandler = (CCStandardTouchHandler*)(pObj);
            if (! pHandler)
            {
                break;
            }
            switch (sHelper.m_type)
            {
            case CCTOUCHBEGAN:
                pHandler->getDelegate()->ccTouchesBegan(pMutableTouches, pEvent);
                break;
            case CCTOUCHMOVED:
                pHandler->getDelegate()->ccTouchesMoved(pMutableTouches, pEvent);
                break;
            case CCTOUCHENDED:
                pHandler->getDelegate()->ccTouchesEnded(pMutableTouches, pEvent);
                break;
            case CCTOUCHCANCELLED:
                pHandler->getDelegate()->ccTouchesCancelled(pMutableTouches, pEvent);
                break;
            }
        }
    }
   //多點(diǎn)觸摸是否釋放
    if (bNeedsMutableSet)
    {
        pMutableTouches->release();
    }
    //
    // Optimization. To prevent a [handlers copy] which is expensive
    // the add/removes/quit is done after the iterations
    //這以下沒研究到底是干什么的 感興趣可以本身看下
    m_bLocked = false;
    if (m_bToRemove)
    {
        m_bToRemove = false;
        for (unsigned int i = 0; i < m_pHandlersToRemove->num; ++i)
        {
            forceRemoveDelegate((CCTouchDelegate*)m_pHandlersToRemove->arr[i]);
        }
        ccCArrayRemoveAllValues(m_pHandlersToRemove);
    }
    if (m_bToAdd)
    {
        m_bToAdd = false;
        CCTouchHandler* pHandler = NULL;
        CCObject* pObj = NULL;
        CCARRAY_FOREACH(m_pHandlersToAdd, pObj)
         {
             pHandler = (CCTouchHandler*)pObj;
            if (! pHandler)
            {
                break;
            }
            if (dynamic_cast<CCTargetedTouchHandler*>(pHandler) != NULL)
            {                
                forceAddHandler(pHandler, m_pTargetedHandlers);
            }
            else
            {
                forceAddHandler(pHandler, m_pStandardHandlers);
            }
         }
 
         m_pHandlersToAdd->removeAllObjects();    
    }
    if (m_bToQuit)
    {
        m_bToQuit = false;
        forceRemoveAllDelegates();
    }
}
如今我們已經(jīng)懂得了 觸屏事宜的調(diào)用流程,我們來看一下 膳綾擎的 m_pTargetedHandlers 變量是怎么添加對象的
先來看一下 CCLayer函數(shù)中得 setTouchEnabled函數(shù) 有如下代碼
void CCLayer::setTouchEnabled(bool enabled)
if (enabled)
{//ture   注冊
   this->registerWithTouchDispatcher();
}
else
{
   // 傳進(jìn)來的是false刪除
    CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
}        
看下這個函數(shù)
void CCLayer::registerWithTouchDispatcher()
{
    CCTouchDispatcher* pDispatcher = CCDirector::sharedDirector()->getTouchDispatcher();
    // Using LuaBindings  用于lua的
    if (m_pScriptTouchHandlerEntry)
    {
    if (m_pScriptTouchHandlerEntry->isMultiTouches())
    {
      pDispatcher->addStandardDelegate(this, 0);
      LUALOG("[LUA] Add multi-touches event handler: %d", m_pScriptTouchHandlerEntry->getHandler());
    }
    else
    {
      pDispatcher->addTargetedDelegate(this,
m_pScriptTouchHandlerEntry->getPriority(), 
m_pScriptTouchHandlerEntry->getSwallowsTouches());
      LUALOG("[LUA] Add touch event handler: %d", m_pScriptTouchHandlerEntry->getHandler());
    }
    }
    else
    {
        if( m_eTouchMode == kCCTouchesAllAtOnce ) {
            pDispatcher->addStandardDelegate(this, 0);
        } else {
            pDispatcher->addTargetedDelegate(this, m_nTouchPriority, true);//把當(dāng)前l(fā)ayer或layer的子類參加 //觸摸優(yōu)先級 //接收到觸摸事宜是否兼并 不向該優(yōu)先級以下 傳遞
        }
    }
}
看下addTargetedDelegate函數(shù) m_pTargetedHandlers 就是我們上文中 touchs函數(shù)中CCTouchHandler * 的數(shù)組
void CCTouchDispatcher::addTargetedDelegate(CCTouchDelegate *pDelegate, int nPriority, bool bSwallowsTouches)
{    
    CCTouchHandler *pHandler = CCTargetedTouchHandler::handlerWithDelegate(pDelegate, nPriority, bSwallowsTouches);
    if (! m_bLocked)
    {
        forceAddHandler(pHandler, m_pTargetedHandlers);
    }
然后再看下forceAddHandler函數(shù),該函數(shù)添加之前須要遍歷一遍數(shù)組,把當(dāng)前參加的CCTouchHandler* 按竽暌古先級參加到已有的CCTouchHandler* 數(shù)組中
大年夜下面的代碼中 我們知道 數(shù)組的排序是按 優(yōu)先級 大年夜小到大年夜分列的   也就是說  設(shè)置的優(yōu)先級 越小,就會最優(yōu)先接收到觸屏事宜
void CCTouchDispatcher::forceAddHandler(CCTouchHandler *pHandler, CCArray *pArray)
{
    unsigned int u = 0;
    CCObject* pObj = NULL;
   //遍歷數(shù)組
    CCARRAY_FOREACH(pArray, pObj)
     {
         CCTouchHandler *h = (CCTouchHandler *)pObj;
         if (h)
         {//比較優(yōu)先級 設(shè)置插入的地位
             if (h->getPriority() < pHandler->getPriority())
             {
                 ++u;
             }
             if (h->getDelegate() == pHandler->getDelegate())
             {
                 CCAssert(0, "");
                 return;
             }
         }
     }
   //向該數(shù)組中 參加該CCTouchHandler *pHandler
    pArray->insertObject(pHandler, u);
}
如今觸摸事宜的流程,我們已經(jīng)知道了,如今來實(shí)現(xiàn)我們本身的觸摸函數(shù)
起首我們要持續(xù)CCLayer函數(shù),重寫接收觸摸事宜的個函數(shù)
class UILayer : public CCLayer
    {
    public:
        UILayer();
        ~UILayer();
    public:
        virtual bool init();
        virtual void onEnter();
        virtual void onExit();
        virtual void registerWithTouchDispatcher();
        virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);
        virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);
        virtual void ccTouchCancelled(CCTouch* touch, CCEvent* event);
        virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);
        CREATE_FUNC(UILayer);
    };
    UILayer::UILayer()
    {
    }
    
    UILayer::~UILayer()
    {
    }
    
    bool UILayer::init()
    {
        if ( !CCLayer::init() )
        {
            return false;
        }
        return true;
    }
    
    void UILayer::onEnter()
    {
        CCLayer::onEnter();
        setTouchEnabled(true);
    }
    
    void UILayer::onExit()
    {
        CCLayer::onExit();
    }
    void UILayer::registerWithTouchDispatcher()
    {
        CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, ROR::TOUCH_UI_PRIORITY, true);//默認(rèn)吞噬觸摸事宜
    }
    
    bool UILayer::ccTouchBegan(CCTouch* touch, CCEvent* event)
    {
CCLOG("ccTouchBegan");
        return true;
    }
    
    void UILayer::ccTouchEnded(CCTouch* touch, CCEvent* event)
    {
CCLOG("ccTouchEnded");
    }
    
    void UILayer::ccTouchCancelled(CCTouch* touch, CCEvent* event)
    {
CCLOG("ccTouchCancelled");
    }
    
    void UILayer::ccTouchMoved(CCTouch* touch, CCEvent* event)
    {
CCLOG("ccTouchMoved");   
    }
 
OK,觸摸事宜已經(jīng)實(shí)現(xiàn)了,可以根據(jù)本身的須要,寫一些邏輯了。


相關(guān)案例查看更多