【cocos2d-x3.2遊戲開發】 模態對話方塊攔截所有事件,cocos2d-x3.2模態

來源:互聯網
上載者:User

【cocos2d-x3.2遊戲開發】 模態對話方塊攔截所有事件,cocos2d-x3.2模態

開發基礎:Cocos2dx 3.2

開發目標:1.實現模態對話方塊,無論彈出多少層都可以攔截事件。 2.ScrollView上有按鈕,可以點擊按鈕滑動,響應事件並且不影響模態對話方塊的事件攔截。



實現方法:
1.Cocos2dx 2版本中,我們會設定DlgLayer事件的優先順序為-128,這樣會攔截底層的按鈕事件(-128),但是問題是會攔截當前層的按鈕事件(-128),需要將DlgLayer上的點擊事件手動傳入對話方塊上的按鈕處理。
3.0版本中已經不再使用了,這種方法有很大的局限性,尤其在介面比較多,比較複雜的情況下,傳遞事件是一種比較挫的做法。直接排除。

2.Cocos2dx 3.X版本中,因為改變了事件的規則,幾乎所有的控制項的事件處理都按SceneGraphPriority走的,甚至連Cocos2dx 2.X版本的Menu的-128也更改為0了。
做法: 直接彈出一個DlgLayer(CCColorLayer), 封裝一個事件吞噬(onTouchBegan, onTouchEnded...), 事件優先順序為addEventListenerWithSceneGraphPriority,即0
 因為所有層的攔截事件優先順序為0,就會先處理最上方的事件,即彈出的對話方塊事件。


特殊情況:
彈出的對話方塊上有ScrollView,ScrollView上有按鈕,最常見的問題就是
1.點擊按鈕能觸發事件,但是點擊按鈕無法滑動ScrollView。
  解決辦法:把按鈕優先順序設定為1(當前ScrollView的優先順序為0),這樣就能點著按鈕滑動了。
  但是產生新問題,按鈕能滑動,卻不能點擊了,因為DlgLayer的優先順序為0,會攔截掉按鈕的事件。

2.有一個特殊的API,setSwallowTouches,在為一個控制項封裝點擊事件的時候,可以將setSwallowTouches(false)。
這就意味著按鈕能夠響應點擊事件,但是因為沒有吞噬事件,就可以把按鈕的事件傳給ScrollView,ScrollView也可以滑動。
DlgLayer 優先順序 0
ScrollView 優先順序 0
Button 優先順序 0
根據ZOrder的順序,先觸發Button,然後是ScrollView,最後是DlgLayer

3. 3.0版本不建議修改priority,因為你無法得知需要彈出多少層對話方塊,就無法確定每個對話方塊的priority

eventdispatcher事件分發規則
添加監聽的方法addEventListenerWithSceneGraphPriority和addEventListenerWithFixedPriority

1.SceneGraphPriority
和Node節點綁定的所有事件的優先順序為0,
添加監聽器後,事件監聽列表內部的排序為 "<0, scene graph (0 priority), >0"

2.FixedPriority
用來自己定製優先順序,一般設定"<0 或 >0"

3. 響應事件的優先順序,數值越小,越先響應,-1 0 1這個順序
內部事件處理順序:
1.優先順序為負數的事件
2.優先順序為0(scene graph)的事件,相同的優先順序會根據Node的z順序高的(繪製於頂部的)節點將優於z順序低的節點。這將保證了諸如觸碰事件的自頂向下傳播。
3.優先順序為整數的事件


最後附帶一個lua版封裝的TouchableSprite

一個可點擊的圖片,可以在ScrollView上點擊滑動,響應事件。


--[[    可點擊的圖片,可以設定響應的優先順序。    比如ScrollView上的按鈕,可以用TouchableSprite實現。將TouchableSprite設定為不吞噬訊息即可。        ~~~lua    -- 點擊點擊事件    local function equip_touch_began_listener(sender, touch, event)    end    -- 點擊結束事件    local function equip_touch_ended_listener(sender, touch, event)        if scroll_view:isTouchMoved() then            return        end                -- 可以添加容錯點擊,如5個像素內。        local start_pt = touch:getStartLocation()        local end_pt = touch:getLocation()        if checkint(start_pt.x) == checkint(end_pt.x) and checkint(start_pt.y) == checkint(end_pt.y) then            print(sender.id_)            print("Ready to equip......")        end    end    -- 添加到ScrollView上可點擊的圖片    local sp = TouchableSprite.new("data/equip.png",                                     equip_touch_began_listener,                                    equip_touch_ended_listener,                                    false)    sp.id_ = 9999    scroll_view:addChild(sp)    ~~~lua]]local TouchableSprite = class("TouchableSprite", function(pic_path)        return display.newSprite(pic_path)    end)TouchableSprite.__index = TouchableSpriteTouchableSprite.listener_ = nilTouchableSprite.swallowTouch_ = trueTouchableSprite.fixedPriority_ = 0TouchableSprite.useNodePriority_ = falseTouchableSprite.removeListenerOnTouchEnded_ = falseTouchableSprite.touch_began_listener_ = nilTouchableSprite.touch_ended_listener_ = nil--[[構造一個可響應點擊事件的TouchableSprite。~~~lua        -- 監聽器有三個參數,第一個參數是自己    local function touch_began_listener(sender, touch, event)    end    local function touch_ended_listener(sender, touch, event)        local start_pt = touch:getStartLocation()        local end_pt = touch:getLocation()        if checkint(start_pt.x) == checkint(end_pt.x) and checkint(start_pt.y) == checkint(end_pt.y) then            print(sender.id_)            print("Ready to equip......")        end    end    local sp = TouchableSprite.new("data/equip.png",             equip_touch_began_listener,            equip_touch_ended_listener)    sp:setTexture("data/equip1.png")    sp:setPriority(1)    parent:addChild(sp)    ~~~lua@param string pic_path 傳入圖片路徑.可為空白,後通過:setTexture("pic_path")重新設定@param touch_began_listener 點擊開始事件的監聽器。為空白時不響應。 監聽器有三個參數,第一個參數是可點擊圖片自己@param touch_ended_listener 點擊結束時事件監聽器。為空白時不響應。 監聽器有三個參數,第一個參數是可點擊圖片自己@param swallow_touch 是否吞噬事件 true 事件不再向下傳遞 false 響應完事件後,繼續向下傳遞]]function TouchableSprite:ctor(pic_path, touch_began_listener, touch_ended_listener, swallow_touch)    self.touch_began_listener_ = touch_began_listener    self.touch_ended_listener_ = touch_ended_listener    self.swallowTouch_ = swallow_touch     local function onNodeEvent(event)        if event == "enter" then            self:onEnter()        elseif event == "exit" then            self:onExit()        end    end        self:registerScriptHandler(onNodeEvent)endfunction TouchableSprite:setTouchBeganListener(touch_began_listener)    self.touch_began_listener_ = touch_began_listenerendfunction TouchableSprite:setTouchEndedListener(touch_ended_listener)    self.touch_ended_listener_ = touch_ended_listenerendfunction TouchableSprite:onEnter()    local eventDispatcher = self:getEventDispatcher()    local function onTouchBegan(touch, event)        local locationInNode = self:convertToNodeSpace(touch:getLocation())        local s = self:getContentSize()        local rect = cc.rect(0, 0, s.width, s.height)                    if cc.rectContainsPoint(rect, locationInNode) then            if self.touch_began_listener_ then                self:touch_began_listener_(self,touch, event)            end            return true        end        return false        end    local function onTouchMoved(touch, event)            end    local  function onTouchEnded(touch, event)        print("onTouchEnded.......")        if self.touch_ended_listener_ then            self:touch_ended_listener_(self, touch, event)        end        if self.removeListenerOnTouchEnded_ then            eventDispatcher:removeEventListener(self.listener_)        end    end    local listener = cc.EventListenerTouchOneByOne:create()    self.listener_ = listener    listener:setSwallowTouches(self.swallowTouch_)        listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN )    listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED )    listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED )    if 0 == self.fixedPriority_ then        eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self)    else        eventDispatcher:addEventListenerWithFixedPriority(listener,self.fixedPriority_)    endendfunction TouchableSprite:setSwalllowTouch(swallow)    self.swallowTouch_ = swallowendfunction TouchableSprite:onExit()    local eventDispatcher = self:getEventDispatcher()    eventDispatcher:removeEventListener(self.listener_)endfunction TouchableSprite:setPriority(fixedPriority)    self.fixedPriority_ = fixedPriority    self.useNodePriority_ = falseendfunction TouchableSprite:removeListenerOnTouchEnded(toRemove)    self.removeListenerOnTouchEnded_ = toRemoveendfunction TouchableSprite:setPriorityWithNode(useNodePriority)    self.fixedPriority_ = 0    self.useNodePriority_ = useNodePriorityendreturn TouchableSprite




Cocos2dx 2.x版本的模態對話方塊:【COCOS2DX-遊戲開發之二】 模態對話方塊


MFC中響應非模態對話方塊的滑鼠移動事件的運行異常

應該是你對話方塊在初始化的時候你就捕獲其滑鼠資訊,對其進行操作導致其發生斷言警告。

你應該在對話方塊初始化完成後再做你的操作。另外因你是響應滑鼠資訊,那你的對話方塊肯定是可見狀態的,所以就用下面這條語句進行判斷。
if (::IsWindowVisible(m_hWnd))
{
//你的處理代碼。

}
else
{
//滑鼠預設響應資訊。

}
 
UG二次開發中可以否調用非模態的MFC對話方塊?

這個問題也討論過很多次了,以前的貼有很多的啊 先建立對話方塊,程式中直接調用下面的子程式即可 void DisplayDialog() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); MyDialog * dlg=new MyDialog(); if(dlg!=NULL) { BOOL ret=dlg->Create(IDD_DIALOG1); if(!ret) AfxMessageBox("Failed create modaless dialog!"); dlg->ShowWindow(SW_SHOW); } }
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.