QuickCocos2dx创建描边效果
@[quick|cocos2d|描边]
参考:
CCRenderTexture这个类平时没怎么用过,想不到用TA来创建描边效果轻松并且效果也还不错。
上面2个帖子的实现,抛开一个c++,一个oc语言来看,我发现思路其实是一样的,这里我翻译了成quick的lua版本,并在代码中相应做了些注释,朋友们可以看下。
-- @param:node 欲描边的显示对象
-- @param:strokeWidth 描边宽度
-- @param:color 描边颜色
-- @param:opacity 描边透明度
function createStroke(node, strokeWidth, color, opacity)
local w = node:getTexture():getContentSize().width + strokeWidth * 2
local h = node:getTexture():getContentSize().height + strokeWidth * 2
local rt = CCRenderTexture:create(w, h)
-- 记录原始位置
local originX, originY = node:getPosition()
-- 记录原始颜色RGB信息
local originColorR = node:getColor().r
local originColorG = node:getColor().g
local originColorB = node:getColor().b
-- 记录原始透明度信息
local originOpacity = node:getOpacity()
-- 记录原始是否显示
local originVisibility = node:isVisible()
-- 记录原始混合模式
local originBlend = node:getBlendFunc()
-- 设置颜色、透明度、显示
node:setColor(color)
node:setOpacity(opacity)
node:setVisible(true)
-- 设置新的混合模式
local blendFuc = ccBlendFunc:new()
blendFuc.src = GL_SRC_ALPHA
blendFuc.dst = GL_ONE
-- blendFuc.dst = GL_ONE_MINUS_SRC_COLOR
node:setBlendFunc(blendFuc)
-- 这里考虑到锚点的位置,如果锚点刚好在中心处,代码可能会更好理解点
local bottomLeftX = node:getTexture():getContentSize().width * node:getAnchorPoint().x + strokeWidth
local bottomLeftY = node:getTexture():getContentSize().height * node:getAnchorPoint().y + strokeWidth
local positionOffsetX = node:getTexture():getContentSize().width * node:getAnchorPoint().x - node:getTexture():getContentSize().width / 2
local positionOffsetY = node:getTexture():getContentSize().height * node:getAnchorPoint().y - node:getTexture():getContentSize().height / 2
local rtPosition = ccp(originX - positionOffsetX, originY - positionOffsetY)
rt:begin()
-- 步进值这里为10,不同的步进值描边的精细度也不同
for i = 0, 360, 10 do
-- 这里解释了为什么要保存原来的初始信息
node:setPosition(ccp(bottomLeftX + math.sin(degrees2radians(i)) * strokeWidth, bottomLeftY + math.cos(degrees2radians(i)) * strokeWidth))
node:visit()
end
rt:endToLua()
-- 恢复原状
node:setPosition(originX, originY)
node:setColor(ccc3(originColorR, originColorG, originColorB))
node:setBlendFunc(originBlend)
node:setVisible(originVisibility)
node:setOpacity(originOpacity)
rt:setPosition(rtPosition)
return rt
end
补充
function degrees2radians(angle)
return angle * 0.01745329252
end
function radians2degrees(angle)
return angle * 57.29577951
end
举个例子
-- 文本、图片一样,这里用文本举个例子
local quickLabel = ui.newTTFLabel({
text = "QuickCocos2dX-createStroke",
color = display.COLOR_RED,
size = 60,
align = ui.TEXT_ALIGN_CENTER,
x = display.cx,
y = display.cy + 150
}):addTo(self, 1)
local renderTexture = createStroke(quickLabel, 4, ccc3(0xca, 0xa5, 0x5f), 100)
-- 设置反锯齿
renderTexture:getSprite():getTexture():setAntiAliasTexParameters()
self:addChild(renderTexture, quickLabel:getZOrder()-1)
这样的方法,会drawcall2次。
群里有朋友提到,如果文本改变,那下方的描边如何做?
那对应的描边renderTexture也需要改变,我想是得先remove掉然后重新创建纹理,那各位可以简单封装下,当文本重新setString
的时候,相应去创建下方的描边纹理就可以了。
最后
如果代码有问题或者其他疑问,欢迎一起探讨学习:)