原文请猛戳:
http://galoisplusplus.coding.me/blog/2015/02/01/label-typewriting-effect/
这次分享一个在cocos2d-x中实现打字特效的小功能。
首先,cocos2d-x中label默认是utf8编码,quickx提供了一个string.utf8len
接口,这里再加一个截取子字符串的函数:
function utf8str(str, start, num)
local function utf8CharSize(char)
if not char then
return 0
elseif char > 240 then
return 4
elseif char > 225 then
return 3
elseif char > 192 then
return 2
else
return 1
end
end
local startIdx = 1
while start > 1 do
local char = string.byte(str, startIdx)
startIdx = startIdx + utf8CharSize(char)
start = start - 1
end
local endIdx = startIdx
while num > 0 do
if endIdx > #str then
endIdx = #str
break
end
local char = string.byte(str, idx)
endIdx = endIdx + utf8CharSize(char)
num = num - 1
end
return str:sub(startIdx, endIdx - 1)
end
第一种实现方式是一开始把每个字符scale到0,延迟一定时间后再scale到原大小:
-- textDelayTime为每个字显示的延迟时间
function typewriting(label, textDelayTime)
string = label:getString()
-- 这里考虑了label可能有换行的情况
local totalLen = string.utf8len(string) + label:getStringNumLines()
for i = 1, totalLen do
local sprite = label:getLetter(i - 1)
if sprite then
sprite:setScale(0)
end
end
local textAppear = cc.ScaleTo:create(0, 1)
for i = 1, totalLen do
local textDelay = cc.DelayTime:create(textDelayTime * (i - 1))
local textActionSeq = cc.Sequence:create(textDelay, textAppear)
local sprite = label:getLetter(i - 1)
if sprite then
sprite:runAction(textActionSeq)
end
end
end
这种实现的效果有跳入感,换一种方式,用visibility来控制:
-- textDelayTime为每个字显示的延迟时间
function typewriting(label, textDelayTime)
string = label:getString()
-- 这里考虑了label可能有换行的情况
local totalLen = string.utf8len(string) + label:getStringNumLines()
for i = 1, totalLen do
local sprite = label:getLetter(i - 1)
if sprite then
sprite:setVisible(false)
end
end
local textAppear = cc.Show:create()
for i = 1, totalLen do
local textDelay = cc.DelayTime:create(textDelayTime * (i - 1))
local textActionSeq = cc.Sequence:create(textDelay, textAppear)
local sprite = label:getLetter(i - 1)
if sprite then
sprite:runAction(textActionSeq)
end
end
end
这种效果也没好多少,最后本渣换了一种思路,不按一个字一个字来runAction了,改为把label作为整体来runAction,在action中去setString,这种方式的效果好多了:
-- textDelayTime为每个字显示的延迟时间
function typewriting(label, textDelayTime)
string = label:getString()
-- 这里考虑了label可能有换行的情况
local totalLen = string.utf8len(string) + label:getStringNumLines()
label:setString("")
local textActions = {}
for i = 1, totalLen do
local textDelay = cc.DelayTime:create(textDelayTime)
local textAppear = cc.CallFunc:create(function()
label:setString(utf8str(string, 1, i))
end)
table.insert(textActions, textDelay)
table.insert(textActions, textAppear)
end
local textActionSeq = cc.Sequence:create(textActions)
label:runAction(textActionSeq)
end
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。