一.学习笔记
1.开关按钮可以使用MenuItemToggle
local toggleItem = cc.MenuItemToggle:create(cc.MenuItemFont:create("Enabled"), cc.MenuItemFont:create("Disabled"))
2.触摸相关
onTouchBegan返回true则可以继续执行onTouchMoved和onTouchEnd
onTouchBegan返回false则此次触摸消息结束,不再执行上述两个方法
setSwallowTouches(true)表示吞掉event,消息不再向底层传递(顶层底层是以zOrder值来看的相对概念)
setSwallowTouches(false)表示消息可以继续传递到下面的层(不常用)
ScrollView/TableView存在一个隐蔽的问题(2.x时代不存在)
假如按钮B存在于ScrollView的内容里或TableView的Cell内
当我们在按钮B上方原地完成一次点击后,按钮B绑定的事件响应,这种情况没问题
当我们在按钮B上方按下鼠标并拖动再抬起时,其绑定事件不响应(也正常)
但ScrollView/TableView没有发生拖动事件
即对于ScrollView即其派生类,从其子节点按钮区域发起的拖动无效!
这里的按钮是UIButton
解决办法:
对按钮设置setSwallowTouches(false)
从继承关系可以看到
class CC_GUI_DLL Button : public Widget
继续看
void Widget::setSwallowTouches(bool swallow)
{
if (_touchListener)
{
_touchListener->setSwallowTouches(swallow);
}
}
只要事件继续传递下去,就会有正确的拖动事件
这里的默认值会导致该问题
所以需要手动设置
3.模态对话框
local eventDispatcher = self:getEventDispatcher()
eventDispatcher:pauseEventListenersForTarget(self, true)
这样暂停了self对象中所有的消息
因此self无法响应触摸事件
例如self是layerA
调用了pause方法后再create一个popupB
并监听popupB的触摸事件或者按钮事件
这样layerA的事件就被很好的屏蔽了
恢复办法
eventDispatcher:resumeEventListenersForTarget(self, true)
另外使用setSwallowTouches的办法也可以屏蔽传递
需要注意的是仅当setSwallowTouches(true)
且onTouchBegan返回true时,才能屏蔽!
可以这样理解,cocos认为这个消息被正确接受了,又被吞了,确实没必要传下去了
第一种方法更方便一些
一方面可以随时切换模态非模态
另一方面弹出层也可以不必监听触摸事件,仅处理按钮
4.按钮长按
local function touchEvent(sender,eventType)
if eventType == ccui.TouchEventType.began then
--鼠标按下
elseif eventType == ccui.TouchEventType.ended then
--鼠标抬起
elseif eventType == ccui.TouchEventType.canceled then
--取消点击
end
end
button:addTouchEventListener(touchEvent)
为按钮注册一个这样的事件监听方法
分别要处理鼠标按下 , 鼠标抬起 , 取消点击三种事件
鼠标按下:
开始一次计时,使用scheduleScriptFunc(func , 0.5 , false)
这样0.5s后会执行func
func中需要关闭schedule,使用unscheduleScriptEntry
若此时尚未抬起鼠标或取消点击
则此时开启一个新的schedule
执行按下时的重复累加逻辑func1(累加方法,传入)
同时记录下此次点击类型是长按
鼠标抬起
首先记录下此次点击结束
其次判断此次点击是否是长按
若是长按,则停止func中开启的schedule
并调用长按结束的回调func2(长按结束方法,传入)
若不是长按,则视为普通单击处理
并调用单击的回调func3(传入)
点击取消
这里只需要处理长按的取消
停止func中开启的schedule
并调用长按结束的回调func2
这样,我们需要3个方法func1,func2,func3
分别处理长按累加过程,长按结束回调,点击回调三种事件
这样我们的按钮就可以兼容单击和长按
二.坑爹笔记
cocos2.x用了快两年的时间
如今换用cocos3.xlua
遇到了不少坑,这里记录一下
1.cellSizeForTable
cocos2.x返回ccsize(width,height)
cocos3.x返回两个数字height,width 顺序竟然反的?!!
2.cocosStudio Node若设置为交互性√会使其作为tablecell的时候无法触摸or滑动
交互性不能打钩
3.今天2016/1/12犯了一个低级错误调了整整一上午
在处理一个简单列表界面的时候
ctor方法中定义了
self.tableView = nil
这是一个好的声明习惯,当然不加也不会有问题
但声明的位置位置位置非常重要!!
正确的做法应该是
self.tableView = nil -- step one
...
self:init() -- step two
在init方法中实例化列表
self.tableView = cc.TableView.create()...
self.tableView:reloadData()
大概是这个样子
但如果把第一步和第二步搞反了
很二
但结果确是一个非常隐蔽的错误
init执行之后,会在tableContainer区域先行渲染一部分cell
比方说numberOfCellsInTableView返回10
而一屏只能显示3个cell
在不拉动屏幕的时候,程序就只会渲染这3个
但是但是但是!!
还没等我们拉动,就错误的执行了self.tableView = nil
于是我们创建的tableView就再也访问不到了
同时如果
tableCellAtIndex
numberOfCellsInTableView
都做了nil保护如
if(self.tableView ~= nil)then return 10 end
return 0
那么程序还不会崩溃
只是拉动的时候发现,除了第一屏,后面没东西了
......
调了一上午,希望以后不能再犯这种低级错误
4.setOpacity/FadeIn/FadeOut无效问题
Node中属性_cascadeOpacityEnabled默认竟然是false
因此设置透明度时,只处理自己,不递归子节点?!
想要递归子节点需要手动设置setCascadeOpacityEnabled(true)
然而很奇怪的是:cocostudio中创建的节点默认就是true