首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

cocos2d-x 快速屏蔽觸摸的兩種方案:優先級攔截法實戰

     編輯:關於C語言

問題背景

cocos2d-x 中 CCDirector::pause() 僅暫停調度器與動作,**觸摸分發器仍在運行**,導致彈窗、計費界面彈出時底層按鈕、菜單仍可觸發,極易造成誤操作與崩潰。

方案一:逐層禁用(不推薦)


layer->setIsTouchEnabled(false); // 對每個 CCLayer/CCMenu 調用

缺陷:同一幀同一函數中先禁用後啟用會觸發斷言崩潰(分發器發現響應列表為空);管理多層狀態繁瑣,易遺漏。

方案二:高優先級攔截層(推薦)

創建一個透明 CCLayer,註冊為**最高優先級、吞噬觸摸**的目標型代理,覆蓋在當前場景最上層。

核心實現


class NoTouchLayer : public CCLayer {
public:
    LAYER_NODE_FUNC(NoTouchLayer);
    virtual bool init();
    virtual void registerWithTouchDispatcher();
    virtual bool ccTouchBegan(CCTouch* pTouch, CCEvent* pEvent);
    virtual void ccTouchMoved(CCTouch* pTouch, CCEvent* pEvent);
    virtual void ccTouchEnded(CCTouch* pTouch, CCEvent* pEvent);
};

bool NoTouchLayer::init() {
    if (!CCLayer::init()) return false;
    setIsTouchEnabled(true);
    return true;
}

void NoTouchLayer::registerWithTouchDispatcher() {
    // INT_MIN 為最高優先級,true 表示吞噬事件不再向下分發
    CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, INT_MIN, true);
    CCLayer::registerWithTouchDispatcher();
}

bool NoTouchLayer::ccTouchBegan(CCTouch* pTouch, CCEvent* pEvent) { return true; }
void NoTouchLayer::ccTouchMoved(CCTouch* pTouch, CCEvent* pEvent) {}
void NoTouchLayer::ccTouchEnded(CCTouch* pTouch, CCEvent* pEvent) {}

使用方式


// 彈窗彈出時
NoTouchLayer* shield = NoTouchLayer::create();
scene->addChild(shield, INT_MAX); // 極大 Z 值確保最上層

// 彈窗關閉時
shield->removeFromParentAndCleanup(true);

優勢總結

  • **零侵入**:無需修改現有層/菜單代碼;
  • **可靠**:吞噬所有觸摸,底層完全不可觸發;
  • **復用性高**:單例或池化管理,全項目通用;
  • **無崩潰風險**:不涉及啟用/禁用狀態切換競態。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved