最近在我开发游戏的时候遇到了这样的一个需求,就是在新手教程的时候要求做一个弹板然后还要让里面的文字一个一个的跳出来,刚开始觉得挺难弄的后来通过在网上查阅里一些资料发现还是挺容易的,我写了一个组件,希望今后在遇到的时候和其他人遇到这种情况的时候能够参考借鉴一下。
进入正题,我先把我写的控件的代码贴出来然后在慢慢讲解:
---------------------------------------------------
--创建新手文本弹出框
--@param pos 要显示的位置 锚点(0.5,0.5)
--@param text 要显示的文字
--@param textSize 文字的字号大小
--@param width 行宽
--@param img 背景图片
--@param dim 模糊程度 取值范围 0 - 1
function createNewbieTextDialog(pos, text, textSize, width, img, dim, lineNum)
assert(Utility:isNotEmptyStr(text),"the information text is not set")
assert(textSize ~= 0,"the textSize is wrong")
assert(width ~= 0,"the width is wrong")
assert(pos,"the pos is nil")
assert(img,"the img is nil")
assert(lineNum,"the lineNum is nil")
local textFonts = {} -- 字符暂时存储的地方
local charArrayFonts = {} --字符存放的地方
local startIndex = 1
local endIndex = 1
local isOk = 0
local charIndex = 1 --字符数组下标
-- 添加字符串数组(判断其中是否有中文字符)
for i = 1, string.len(text) do
local curByte = string.byte(text, i)
local byteCount = 1 -- Utf8 编码最大有4個字節的情況
-- 判断编码类型
if curByte > 0 and curByte <= 127 then
byteCount = 1
elseif curByte >= 192 and curByte < 223 then
byteCount = 2
elseif curByte >= 224 and curByte < 239 then
byteCount = 3
elseif curByte >= 240 and curByte <= 247 then
byteCount = 4
end
endIndex = i + byteCount - 1
textFonts[i] = string.sub(text, startIndex, endIndex)
startIndex = endIndex + 1
if byteCount ==3 then
charArrayFonts[charIndex] = textFonts[i]
print("pppppp"..charArrayFonts[charIndex])
charIndex = charIndex + 1
isOk = 2
elseif byteCount == 1 then
if isOk <= 0 then
charArrayFonts[charIndex] = textFonts[i]
print("HHHHHH"..charArrayFonts[charIndex])
charIndex = charIndex + 1
end
isOk = isOk - 1
end
-- 讲字符串数组传入正确的字节数和值
--print("##########"..textFonts[i].."@@@@@@@@@"..startIndex.."^^^^^^^"..byteCount)
end
local popLayer = nil --弹出层
local function onTouchBegan(touch,event)
return true
end
--移除弹出层
local function onTouchEnded(touch,event)
cc.Director:getInstance():getRunningScene():removeChild(popLayer,true)
return true
end
--注册触摸事件
local function registerTouchEvent()
local listener = cc.EventListenerTouchOneByOne:create();
listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN)
listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED)
listener:setSwallowTouches(true)
cc.Director:getInstance():getEventDispatcher():addEventListenerWithSceneGraphPriority(listener,popLayer);
end
local bgimv=ccui.ImageView:create(img)
bgimv:setContentSize(cc.size(width+50,lineNum * textSize+50)) --50 像素为底部背景比文字大出来的边框
bgimv:setScale9Enabled(true)
bgimv:setPosition(pos)
popLayer = cc.LayerColor:create(cc.c4b(0,0,0,255*dim%255))
popLayer:setPosition(cc.p(0,0))
popLayer:addChild(bgimv)
-- 弹板上的文字
local layerHeight = nil
local tipLable = {}
local i = 1
local j = 0 -- 可能转到第二行
-- 调度函数
local function scheduleUpdate(dt)
tipLable = cc.Label:createWithSystemFont(charArrayFonts[i],"fonts/Marker Felt.ttf",textSize,cc.size(width,-1))
tipLable:setColor(cc.c3b(255,255,255))
layerHeight = tipLable:getContentSize().height
tipLable:setAnchorPoint(cc.p(0.5,0.5))
tipLable:setPosition(pos)
tipLable:setPositionX(pos.x + i * textSize)
if pos.x + i * textSize >= 1.5 * width then -- 自动换行,最多两行
tipLable:setPositionY(pos.y - textSize)
tipLable:setPositionX(pos.x + j * textSize)
j = j + 1
end
i = i + 1
print(i.."##########"..charArrayFonts[i])
popLayer:addChild(tipLable) -- 添加文字
if i >= #charArrayFonts then
cc.Director:getInstance():getScheduler():unscheduleScriptEntry(Schedule.id)
end
end
--创建调度者
Schedule.id = cc.Director:getInstance():getScheduler():scheduleScriptFunc(scheduleUpdate, 0.1, false)
registerTouchEvent() -- 注册触摸监听事件
cc.Director:getInstance():getRunningScene():addChild(popLayer) -- 在当前场景添加层
end
在上面的这一长串的代码里,也基础的一般都能看懂,但里面核心实现让文字一个一个的跳出来还是靠的中间的那段代码(--添加字符串数组(判断是否有中文字符))从那段带代码移植到for循环结束,这里面主要的参数其实就是传进来一个字符串,然后第一次截取一个字符,第二次截取两个字符,依次类推但是要注意的是,这段字符串里面可以有标点符号的,再使用string.byte去字符的时候要注意中文是占两个位置的而其他的符号是占一个位置的,所以这里分了四个区间来区分所占的位置,我们这里会用到的一般就是3和1这两个位置,分别表示的是中文和特殊符号。将字区分好了,剩下的就使用调度者去调度让这些字显现出来