在做格斗类游戏的时候,有摇杆和攻击键两个sprite,我想要的是一只手指按下摇杆的时候另一只手指还能操作攻击键,但实际上第二根手指完全没反应。
local spr1 = display.newSprite(image1)
spr1:addNodeEventListener(cc.NODE_TOUCH_EVENT, function(event)
if event.name ~= "moved" then
print("spr1 " .. event.name)
end
if event.name == "began" then return true end
end)
spr1:setTouchEnable(true)
local spr2 = display.newSprite(image2)
spr2:addNodeEventListener(cc.NODE_TOUCH_EVENT, function(event)
if event.name ~= "moved" then
print("spr2 " .. event.name)
end
if event.name == "began" then
return true
end
end)
spr2:setTouchEnable(true)
```
Test1: 先按下spr1,然后按下屏幕任何一处(包括spr1和spr2),输出信息只有一个 "spr1 began"(即第二个手指没有任何输出)
Test2: 设置spr2:setTouchMode(cc.TouchesAllAtOnce), 先按下spr2,然后按下屏幕任何一处,输出信息"spr2 began" "spr2 added" (即第一个对象没有任何输出)
在经过各种折腾、死掉无数脑细胞后终于找到LuaTouchEventManager,在onTouchesBegan函数里找到罪魁祸首:
// check current in touching
if (_touchingTargets.size())
{
dispatchingTouchEvent(touches, event, CCTOUCHADDED);
return;
}
_touchingTargets是记录began返回true的对象
Test1: _touchingTargets在第一个手指按下后存着spr1,size不为0给
_touchingTargets中对象派发CCTOUCHADDED,而dispatchingTouchEvent里面有这么一些代码
if (touchMode == LuaEventNode::modeTouchesAllAtOnce)
{
switch (event)
{
case CCTOUCHMOVED:
case CCTOUCHENDED:
case CCTOUCHCANCELLED:
case CCTOUCHADDED:
case CCTOUCHREMOVED:
}
}
else
{
switch (event)
{
case CCTOUCHMOVED:
case CCTOUCHENDED:
case CCTOUCHCANCELLED:
case CCTOUCHREMOVED:
}
}
```
这次的模式是OneByOne,所以进到else,然后发现没有CCTOUCHADDED的分支,所以不再继续任何派发
Test2: _touchingTargets在第一个手指按下后存着spr2,size不为0给
_touchingTargets中对象派发CCTOUCHADDED,这次模式为AllAtOnce,所以触摸任何地方都给第二个对象派发CCTOUCHADDED
不知道这算是bug还是quickx特意设置的,反正是感觉很不好用,个人感觉功能应该是这样的
for node in allNodes do
for touch in allTouches do
if touch in spr's cascadeBoundingBox then
if firstTouch in spr or mode is onebyone then
dispatch("began")
else
dispatch("added")
end
end
end
end
```
即无论OneByOne还是AllAtOnce都可以派发added和removed,但是added派发前都要检测cascadeBoundingBox