quick中自定义事件

quick中的事件机制在官方的文档中已经讲解得很清楚了 http://cn.cocos2d-x.org/article/index?type=quick_doc&url=/doc/cocos-docs-master/manual/framework/quick/V3/events/zh.md
这些方法能处理绝大多数的事件,但如果要实现自定义的事件(例如我们自己实现一个类,对该类添加自定义的事件处理)就需要对类进行扩展了。

下面讲讲如何使用自定义(扩展)的事件机制。

首先认识一下类EventProxy,就是这个类实现了自定义的消息处理
该类有四个函数,分别是

addEventListener
removeEventListener
removeAllEventListenersForEvent
removeAllEventListeners


```

根据名字就能知道这几个函数的作用

下面以我们定义一个继承自Node的类来了解自定义事件的处理方法
定义类EXNode如下
local EXNode = class("EXNode", function()
    return display.newNode()
end)

function EXNode:ctor()
    cc.GameObject.extend(self):addComponent("components.behavior.EventProtocol"):exportMethods()

    cc.ui.UIPushButton.new({normal = "button/button_normal.png", pressed = "button/button_selected.png"})
        :align(display.CENTER, display.cx, display.cy)
        :onButtonClicked(function()
            self:getChildEvent()
        end)
        :addTo(self)
end

function EXNode:getChildEvent()
   self:dispatchEvent({name = "MY_NEWS"})
end

function EXNode:onEnter()
    self:setTouchEnabled(true)
end

function EXNode:onExit()
    self:removeAllEventListeners()
end

return EXNode


```

最重要的是这句cc.GameObject.extend(self):addComponent("components.behavior.EventProtocol"):exportMethods()
该句为EXNode类添加了扩展的事件处理方法,现在我们可以使用EventProxy中的函数了,通过这些函数我们可以让EXNode接收到自定义的消息然后进行处理
在该类中我们创建一个按钮,用按钮来模拟我们游戏中的某些操作,当按钮按下的时候发送消息给其父节点EXNode,我们将该自定义的消息名字设置为MY_NEWS

我们在Scene中使用EXNode
local EXNode = import("..class.EXNode")

local EventScene = class("EventScene", function()
    return display.newScene("EventScene")
end)

function EventScene:ctor()
    self.exNode = EXNode.new()
    self.exNode:addEventListener("MY_NEWS", handler(self, self.onMynews))
    self:addChild(self.exNode)
end

function EventScene:onMynews()
    printLog("INFO","父Node知道了子Node发送过来的消息")
end

function EventScene:onEnter()
end

function EventScene:onExit()
end

return EventScene


```


在EventScene中创建一个EXNode对象,
self.exNode:addEventListener("MY_NEWS", handler(self, self.onMynews))让exNode对象监听自定义的事件,
从这句可以看到我们监听的事件信息名称为MY_NEWS(即EXNode中按钮点击后发送的自定义消息),回调函数为EventScene的onMynews函数

测试程序,点击按钮模拟游戏操作,在EXNode内部分发出名称为MY_NEWS的消息,之后exNode对象就能够接收到消息,然后调用回调函数onMynews进行处理了。


其实内容很简单,给新手入门用吧,大神自动忽略。
第一次尝试写这个,如有错误,希望大家指出。

我研究了两天昨晚才看懂,你今天就发这篇:10:,为什么不早点发呢:6:,百度没有,源码没注释,这篇必须推

components.behavior.EventProtocol 一点也不好看的API写法。。自己写了套MessageManager

我就是写着玩玩:7:,现在回过头来看,果然感觉很烂。。。。。。你的连载要继续更新啊,大家都等着呢:867:

有好东西拿出来分享下呗

MessageManager.lua文件


Msglisteners = {}
    
function addMessage(target,msg,backFunc)
    local msgObj = {body = target,func = backFunc}
    if Msglisteners == nil then
        Msglisteners = {}
    end 
    if hasMessage(msg,backFunc) then
        return
    end
    table.insert(Msglisteners, msgObj)
end

function sendMessage(data)
    -- body
    local msgs = Msglisteners
    if msgs == nil then 
        return
    end
    for k,l in pairs(msgs) do
        local func = l"func"]
        local body = l"body"]
        func(body,data)
    end
end

function hasMessage(msg,func)
    -- body
    local msgs = Msglisteners
    for k,v in pairs(msgs) do
        if v"func"] == func then
            return true;
        end
    end
    return false
end

--
 * 
 * @param  {} msgNa
 * @return {}
 ]]
function removeMessageByName(msgNa)
    -- body
    Msglisteners = nil
end

--
 * 
 * @param  {} target
 * @return {}
 ]]
function removeMessageByTarget(target)
    -- body
    for i,j in pairs(Msglisteners) do
        for k,l in pairs(j) do        
            local tempTarget = l"body"]
            if tempTarget == target then
                table.remove(j, k)
            end
        end
    end
end

--
 * 
 * @param  {} target
 * @param  {} msg
 * @return {}
 ]]
function removeMessageFromTargetByName(target,msg)
    -- body
    local msgs = Msglisteners
    for k,v in pairs(msgs) do
        if v"body"] == target then
            table.remove(msgs, k)
        end
    end
end

function removeAllMessage( ... )
    -- body
    Msglisteners = {}
end

使用
先require(“MessageManager”)

类A中:
local function onRefreshGame()
print("--------onRefreshGame---------")
end
addMessage(self, “REFRESH_GAME”,onRefreshGame)
类B中
sendMessage({msg =“REFRESH_GAME”})

我发现有些地方没有定义event或者参数传进来,就使用了event。

是的 没传event进去。

这篇文章绝对误人子弟,eventproxy与EventProtocol是两套实现方案