简易新手引导
来源:互联网 发布:淘宝 发送会员卡 编辑:程序博客网 时间:2024/05/17 03:48
前面介绍了ClippingNode的简单使用,补充说明setAlphaThreshold方法设定alpha阈值,只有模板(stencil)中像素的alpha值大于alpha阈值时,内容才会被绘制。默认为1,当为1时,模板全部绘制。若不是1,表示只绘制模板中alpha像素大于阈值的内容。
所以当setAlphaThreshold(1.0f)时,stencil全部绘制(红框内的全部),setInverted(false)显示被模板裁剪下来的底板内容是一个右图大小的草地图片,setInverted(true)显示剩余部分。
结合之前用到的屏蔽触摸的层,做一个简易的新手引导。
首先在MainScene中添加了2个Button
function MainScene:createUI() local _size = cc.Director:getInstance():getWinSize() local function btnClicked(sender,_type) print('--btn click--') end local btn = ccui.Button:create('res/DS07.png','res/DS08.png','res/DS09.png') self:addChild(btn) btn:setPosition(_size.width/3,_size.height/3) btn:addTouchEventListener(btnClicked) local function btnClicked2(sender,_type) print('--btn2 click--') end local btn2 = ccui.Button:create('res/DS10.png','res/DS11.png','res/DS12.png') self:addChild(btn2) btn2:setPosition(_size.width/3,_size.height/4.5) btn2:addTouchEventListener(btnClicked2)end
运行->
在新手引导时,需要玩家去点击Auto按钮,其他可以互动的控件全部不能响应,而且需要在视觉上将Auto按钮所在地方点亮,其他地方蒙蔽,那么可以结合之前的ClippingNode和屏蔽触摸层来实现。
新建一个Lua文件,代码:
local GuideShade = class('GuideShade',function () return cc.Node:create() end)function GuideShade:ctor(x,y) self.x = x self.y = y self:createUI() self:openTouch()endfunction GuideShade:createUI() local stencil = cc.Sprite:create('res/mask.png') self.r = stencil:getContentSize().width / 2 local clipping = cc.ClippingNode:create(stencil) clipping:setInverted(true) clipping:setAlphaThreshold(0.3) self:addChild(clipping,-1) clipping:setPosition(self.x,self.y) local pb = require("app/views/Pingbilayer").new() clipping:addChild(pb) pb:setPosition(-self.x,-self.y)endfunction GuideShade:checkPointInCircle(c_x,c_y) local d_x = math.abs(c_x - self.x) local d_y = math.abs(c_y - self.y) local distance = math.pow(d_x,2) + math.pow(d_y,2) if math.sqrt(distance) < self.r then return true end return falseendfunction GuideShade:openTouch() local listener = cc.EventListenerTouchOneByOne:create() local contain = false local function onTouchBegan( touch,event ) local pos = touch:getLocation() if self:checkPointInCircle(pos.x,pos.y) then contain = true else contain = false end return true end local function onTouchMoved( touch,event ) end local function onTouchEnded( touch,event ) local pos = touch:getLocation() if contain and self:checkPointInCircle(pos.x,pos.y) then print('--in circle--') end end listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN) listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED) listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED) self:getEventDispatcher():addEventListenerWithSceneGraphPriority(listener,self) local function onNodeEvent(event) if event == 'exit' then self:getEventDispatcher():removeEventListener(listener) end end self:registerScriptHandler(onNodeEvent)endreturn GuideShade
在createUI方法中用到的模板:,所以点亮的地方是一个圆形,参数x,y为这个圆在世界坐标系中的位置。剪裁节点添加了屏蔽触摸的层,那么在GuideShade这个Node之下的控件将无法监听到触摸事件。
将GuideShade添加到MainScene中
function MainScene:onEnter() local _size = cc.Director:getInstance():getWinSize() local sp=cc.Sprite:create('res/HelloWorld.png') self:addChild(sp) sp:setPosition(_size.width/2,_size.height/2) self:createUI() self:openTouch() self:guide(_size)endfunction MainScene:guide(_size) local guideLayer = require('app/views/GuideShade').new(_size.width/3,_size.height/3) self:addChild(guideLayer)end
由于屏蔽了触摸,2个按钮都不能点击,function GuideShade:checkPointInCircle(c_x,c_y)判断了点击点是否在圆内,只有当触摸开始的点在圆内以及结束点也在圆内时,输出了–in circle–。
现在视觉上除了Auto按钮上方的圆点亮之外,其他地方都蒙灰了,且点击圆之外的地方,都没有反应(屏蔽层有反应),但是点击圆内的位置也没有反应,所以需要在引导时将要引导的数据传递过来,在点击圆内时响应原本Auto按钮的事件。
下面是MainScene中添加了模拟数据后的完整代码:
local MainScene = class("MainScene", cc.load("mvc").ViewBase)local _data = {['1'] = {normal = nil,pressed = nil,disabled = nil,event = nil,name = nil}, ['2'] = {normal = nil,pressed = nil,disabled = nil,event = nil,name = nil}}function MainScene:ctor() self:enableNodeEvents()endfunction MainScene:onEnter() local _size = cc.Director:getInstance():getWinSize() local sp=cc.Sprite:create('res/HelloWorld.png') self:addChild(sp) sp:setPosition(_size.width/2,_size.height/2) self:createUI() self:openTouch() self:guide(_size)endfunction MainScene:createUI() local _size = cc.Director:getInstance():getWinSize() local function btnClicked(sender,_type) print('--btn click--') end local btn = ccui.Button:create('res/DS07.png','res/DS08.png','res/DS09.png') self:addChild(btn) btn:setPosition(_size.width/3,_size.height/3) btn:addTouchEventListener(btnClicked) local function btnClicked2(sender,_type) print('--btn2 click--') end local btn2 = ccui.Button:create('res/DS10.png','res/DS11.png','res/DS12.png') self:addChild(btn2) btn2:setPosition(_size.width/3,_size.height/4.5) btn2:addTouchEventListener(btnClicked2) _data['1'].normal = 'res/DS07.png' _data['1'].pressed = 'res/DS08.png' _data['1'].disabled = 'res/DS09.png' _data['1'].event = btnClicked _data['2'].normal = 'res/DS10.png' _data['2'].pressed = 'res/DS11.png' _data['2'].disabled = 'res/DS12.png' _data['2'].event = btnClicked2endfunction MainScene:openTouch() local listener = cc.EventListenerTouchOneByOne:create() local function onTouchBegan( touch,event ) print("--touchBegan--") return true end local function onTouchMoved( touch,event ) print("--touchMoved--") end local function onTouchEnded( touch,event ) print("--touchEnded--") end listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN) listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED) listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED) self:getEventDispatcher():addEventListenerWithSceneGraphPriority(listener,self) local function onNodeEvent(event) if event == 'exit' then self:getEventDispatcher():removeEventListener(listener) end end self:registerScriptHandler(onNodeEvent)endfunction MainScene:guide(_size) local guideLayer = require('app/views/GuideShade').new(_size.width/3,_size.height/3,_data) self:addChild(guideLayer)endreturn MainScene
_data中保存了2个按钮的数据,那么在创建GuideShade时传入这个数据,在开始结束都点在圆内时响应按钮的事件。
local function onTouchEnded( touch,event ) local pos = touch:getLocation() if contain and self:checkPointInCircle(pos.x,pos.y) then print('--in circle--') local func = self._data['1'].event if func then func() end end end
点圆可以看到
输出了–btn click–,原来点击Auto会输出2个–btn click–是因为,在回调函数中没有对事件进行判断,在点击到按钮的began和ended时都调用了回调函数,所以输出有2个,如果点到按钮之后moved会输出更多。而且回调函数有2个参数。在点击圆之后只是调用了这个回调函数,只输出了一次,并且没有2个参数,无法获得按钮以及事件,sender参数是可以通过_data记录并在调用回调函数时使用,在_data中添加一个sender,
local _data = {['1'] = {normal = nil,pressed = nil,disabled = nil,event = nil,name = nil,sender = nil}, ['2'] = {normal = nil,pressed = nil,disabled = nil,event = nil,name = nil,sender = nil}}_data['1'].sender = btnprint('--in circle--')local func = self._data['1'].eventlocal sender = self._data['1'].senderif func then func(sender)end
这里用的是一个圆形的模板,那么就有一个体验不好的地方,如果点击的点在圆内,但是在按钮外边,仍然能响应事件,这里需要做优化。另外,原本点击按钮时,有按钮的点击效果,现在没有这个按下去的效果,因为根本不是真正的点中了按钮,不过在_data中记录有这个按钮的资源,可以再创建一个按钮摆放在那个位置。
如果_data中记录有按钮本身,那么可以有个更好的办法,在GuideShade中,
function GuideShade:createUI() local stencil = cc.Sprite:create('res/mask.png') self.r = stencil:getContentSize().width / 2 local clipping = cc.ClippingNode:create(stencil) clipping:setInverted(true) clipping:setAlphaThreshold(0.3) self:addChild(clipping,-1) clipping:setPosition(self.x,self.y) local pb = require("app/views/Pingbilayer").new() clipping:addChild(pb) pb:setPosition(-self.x,-self.y) local sender = self._data['1'].sender local btn = sender:clone() self:addChild(btn) btn:setPosition(self.x,self.y)end
createUI方法中直接clone了按钮并摆放在原本按钮上方,这个clone出的按钮和原来的按钮用同一个回调函数,并且2个参数都能获取
这样不仅有按钮的点击效果,有按下去的感觉,而且在回调函数中能获取按钮和事件2个参数。不过这样也有一个缺点,就是看起来整个按钮都在圆形的上方,视觉效果不好。在实际开发中,还需要根据需求选择合适的方案。
- 简易新手引导
- 新手引导
- 新手引导
- 新手引导
- 新手引导
- 游戏新手引导设计
- app 新手引导功能设计
- cocos2d-x 新手引导
- cocos2d-x 新手引导
- cocos2d-x 新手引导
- COCOS2D-X 新手引导
- cocos2d-x 新手引导
- cocos2d clippindNode,新手引导
- cocos2dx 新手引导
- cocos2d3.5新手引导
- cocos2dx 新手引导层
- 新手引导!quick
- js新手引导
- 各种编码规则
- 数组和List之间相互转换的方法
- 我的计划
- jQuery绑定方法的区别 - .bind() / .live() / .delegate() / .on()
- 设置eclipse4.4 JDK, MAVEN目录
- 简易新手引导
- 仿product hunt 头像收起展开的效果
- SQLServer使用sql语句复制数据库
- c语言学习(3)
- H264学习_基本数据结构
- 【高斯消元】BZOJ 1013: [JSOI2008]球形空间产生器sphere
- was内存溢出:native memory exhausted(本地溢出)
- [Yii2.0 TimestampBehavior]
- java用一行代码初始化ArrayList