一、自定义按钮 BubbleButton
上一篇链接:http://www.cocoachina.com/bbs/read.php?tid=233838
上一篇我们讲到 气泡按钮 BubbleButton 的传入参数是:{ imgae = XXX, sound = XXX, prepare = XXX, listener = XXX },大家努力回想一下,使用过程中,
image是一张图片,
sound是一个音频文件,
prepare和listener都是一个方法。
使用代码(MeunScene.lua中的):
-- 3、“更过游戏”按钮
self.moreGamesButton = BubbleButton.new({
image = "#MenuSceneMoreGamesButton.png",
sound = GAME_SFX.tapButton,
prepare = function()
audio.playSound(GAME_SFX.tapButton)
self.startButton:setButtonEnabled(false)
end,
listener = function()
app:enterMoreGamesScene()
end,
})
:align(display.CENTER, display.left + 150, display.bottom + 300)
:addTo(self)
```
现在我们来正式了解下这个自定义的按钮。
打开src\app\views\BubbleButton.lua, 看看代码,这个就不贴代码,贴的太多就磨灭大家的看帖动力了。还贴图更有动力,大家也用play3多看看效果,感觉更爽
粗略一看之后是不是觉得代码很多很乱很烦啊?其中仔细看看就会发现这个脚本里面只有一个方法,就是 new(param)
而其作用很明显:对参入的参数进行捕获,创建一个PushButton, 并封装进动作效果
整个方法内代码很多,头一次看会很乱,我先*
隐藏一部分代码*(为了方便理解,我改动了一点点顺序,但对程序没有丝毫影响)
大家就会发现该方法其实只干了4件事情,如下:
function BubbleButton.new(params)
-- 1、创建PushButton,只设置了normal情况下图片(既是传入参数中的image的值)
local button = cc.ui.UIPushButton.new({normal = params.image})
-- 2、将传入的回调函数先用listener变量保存起来,
local listener = params.listener
-- 3、重新定义了传入参数中 params.listener的执行内容
params.listener = function(tag)
-- 4、设置按钮点击响应事件
button:onButtonClicked(function(tag)
-- 返回该按钮
return button
end
```
1、 创建按钮:没什么好讲的,大家这么聪明肯定都懂得。但是还是建议大家多看看Quick的框架源码,里面的有中文注释,很好理解,对学习Quick帮助极大,路径就在Quick-Cocos2d-x v3.2-RC0所在目录的quick-cocos2d-x-3.2rc0\quick\framework 里。
2、 捕获传入参数中的listener元素:由本地变量listener保存起来(我好讨厌名字一样啊,有时老不小心就看错!)。 为什么要找个本地变量来存储呢?等下你就知道了
3、 重新定义传入参数中的元素listener:有人也许会问:要重新定义,原来传入的有什么意思呢? 往上看看第2点,现在知道为什么要本地变量listener保存了吧。 现在我们把第3点的代码展开,看看里面做些什么事情
-- 3、重新定义了参数表中 params.listener的执行内容
params.listener = function(tag)
-- (1)如果参数中 prepare的值不为空,则先执行params.prepare()
if params.prepare then
params.prepare()
end
-- (2)zoom1和zoom2是两个效果函数,主要是move和scale两个动作,
local function zoom1(offset, time, onComplete)
local x, y = button:getPosition()
local size = button:getContentSize()
size.width = 200
size.height = 200
local scaleX = button:getScaleX() * (size.width + offset) / size.width
local scaleY = button:getScaleY() * (size.height - offset) / size.height
transition.moveTo(button, {y = y - offset, time = time})
transition.scaleTo(button, {
scaleX = scaleX,
scaleY = scaleY,
time = time,
onComplete = onComplete,
})
end
local function zoom2(offset, time, onComplete)
local x, y = button:getPosition()
local size = button:getContentSize()
size.width = 200
size.height = 200
transition.moveTo(button, {y = y + offset, time = time / 2})
transition.scaleTo(button, {
scaleX = 1.0,
scaleY = 1.0,
time = time,
onComplete = onComplete,
})
end
-- (3)动作效果方法的组合使用
-- 设置按钮的点击功能无效,防止在还没做完动作又被玩家点上该按钮
button:setButtonEnabled(false)
-- 执行动作效果, 一系列的缩放效果之后,再开启按钮功能,最后执行之前的回调函数,这样一个动画按钮就新鲜出炉了。
zoom1(40, 0.08, function()
zoom2(40, 0.09, function()
zoom1(20, 0.10, function()
zoom2(20, 0.11, function()
button:setButtonEnabled(true) -- 动作效果结束后,开启按钮的点击功能
listener(tag) -- 执行原先的params.listener的方法
end)
end)
end)
end)
end
```
重新定义了的param,listener 还是一个方法,该方法里的代码可以分成三部分:
(1)执行param.prepare这个元素所指向的方法;
if params.prepare then
params.prepare()
end
该部分用了if判断语句,如果params.prepare 为空则不会执行,所以根据实际情况,传入参数中的元素prepare并不是一个必填项。
(2)定义了两个本地的效果方法zoom1和zoom2;
zoom1和zoom2是两个效果函数,主要是move和scale两个动作,这个两个内容不难,我就不讲解了,大家看看理解下就好
(3)动作效果方法的组合使用;
使用zoom1和zoom2进行组合使用,达到气泡效果的动作。难度不大但需要注意几点:
A、使用回调函数,使动作连续
B、执行动作效果前,先关闭该PushButton的按钮功能,防止在还没做完动作又被玩家点上该按钮:button:setButtonEnabled(false) , 效果结束了后在开启它的按钮功能
C、在动作效果结束时,还在要执行之前我们用本来变量listener保存下来的方法,就是这个句代码:listener(tag),因为动作效果是我们附加的视觉效果,listener的方法才我们真正效果,不要忘本了哦
4、 设置按钮点击响应事件:代码展开如下
button:onButtonClicked(function(tag)
params.listener(tag)
end)
```
是不是很简单,就是执行了我们刚才重新定义了的params.listener,
params.listener已经把所有需要做的事都做了:执行params.prepare、动作效果、还有最初的params.listener所定义的方法(如今在本地变量listener里)
现在再重新梳理一下,传入参数{ imgae = XXX, sound = XXX, prepare = XXX, listener = XXX }
image 是用于创建PushButton的图片,必须
sound 在BubbleButton.lua并没用到,但它其实是按钮被点击时的效果声音,等下再解释
prepare 是一个必定会被执行到的方法,但可以置空,大家就根据实际情况决定要不要写,应该写些什么。根据它的的名字,我理解这个元素是按钮被点击前需要做的事。
listener 同样是一个必定被执行的方法
再回到MenuScen.lua的ctor()的方法中,找到使用了BubbleButton的代码
--“开始”按钮
self.startButton = BubbleButton.new({
image = "#MenuSceneStartButton.png",
sound = GAME_SFX.tapButton,
prepare = function()
audio.playSound(GAME_SFX.tapButton) -- 播放特效声
--self.startButton:setButtonEnabled(false)
self.moreGamesButton:setButtonEnabled(false) -- 先关闭功能,这样防止还没做完动作又被玩家点上别的按钮上了
end,
listener = function()
app:enterChooseLevelScene() -- 该方法在MyApp.lua中
end,
})
:align(display.CENTER, display.right - 150, display.bottom + 300) -- 设置锚点,X坐标,Y坐标
:addTo(self) -- 添加到该场景中
```
注释应该很清楚了,最后我想提出一下自己的改动:
看上面的代码,是不是有一句与原代码不同?就是注释掉了self.startButton:setButtonEnabled(false) ,并添加了 self.moreGamesButton:setButtonEnabled(false) , 请让我解释一下, 原先的 self.startButton:setButtonEnabled(false) 这句代码的作用关闭startButton这个按钮的点击,防止这个按钮在还没做完动作又被玩家点上,但是看过BubbleButton.lua里面的代码后发现关闭按钮功能的代码已经内嵌在其中了,这样就发生了代码功能重复,所以我认为 self.startButton:setButtonEnabled(false) 这句代码是多余。
而添加了self.moreGamesButton:setButtonEnabled(false) 这句目的很简单,因为在MenuScene的场景一共就两个由BubbleButton 创建出来的按钮:startButton和moreGamesButton, 我希望在点击其中一个按钮时,另外的一个按钮的点击功能会被禁用,用户体验才更好(同时在另外一个按钮代码也应该做相应的修改)
以上只是我个人的理解,不知道对不对,大家多担当,多给建议
同时,对于这个二次封装的按钮,大家也可以看看这位大神讲解http://cn.cocos2d-x.org/tutorial/show?id=1350
二、进入MoreGamesScene场景
完全了解MenuScene这个场景后,我们随着startButton和moreGamesButton这两个按钮进入其他场景,继续学习吧
首先,点击moreGamesButton,我们将进入MoreGamesScene场景,如下图:
真是单调的界面啊,我们还是打开src\app\scenes\MoreGamesScene.iua来直接看代码吧:
-- 导入AdBar.lua
local AdBar = import("..views.AdBar")
-- 创建一个名为MoreGamesScene的场景类
local MoreGamesScene = class("MoreGamesScene", function()
return display.newScene("MoreGamesScene")
end)
function MoreGamesScene:ctor()
-- 1、背景
self.bg = display.newSprite("#MenuSceneBg.png", display.cx, display.cy)
self:addChild(self.bg)
--2、信息条
self.adBar = AdBar.new()
self:addChild(self.adBar)
--3、后退按钮
cc.ui.UIPushButton.new("#BackButton.png")
:align(display.CENTER, display.right - 100, display.bottom + 120)
-- 添加点击的响应事件
:onButtonClicked(function()
app:enterMenuScene() -- 回到MenuScene中
end)
:addTo(self)
end
return MoreGamesScene
```
1、背景:创建一精灵,并添加到场景中
2、信息条:在上一篇中已经大胆预测它会再出现了,果不其然啊,不到多少,大家自己看代码吧
3、后退按钮:使用是Quick框架封装好的PushButton按钮创建,源码在quick-3.2rc0-win\quick-cocos2d-x-3.2rc0\quick\framework\cc\ui,大家要养成多查看框架代码的习惯,用法里面讲得很清楚
这个场景太简单了,没什么好讲,我们还是默默的按后退键吧

顶一个,写的好