cocos2dx lua 描边

这篇博客介绍了如何在Cocos2d-x Lua中为精灵添加描边和阴影效果。通过创建一个名为`ui.createShadowStroke`的函数,该函数接受精灵对象和参数,包括阴影偏移、颜色、不透明度和描边大小等,然后计算并绘制描边和阴影,最后将结果保存到一个RenderTexture中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

function ui.createShadowStroke(sprite, params)
    local shadowOffset = params.shadowOffset
    local shadowColor = params.shadowColor
    local shadowOpacity = params.shadowOpacity
    local strokeSize = params.strokeSize
    local strokeColor = params.strokeColor
    local strokeOpacity = params.strokeOpacity
    local pixelFormat = params.pixelFormat
    if type(shadowOffset) == "number" then shadowOffset = ccp(shadowOffset, - shadowOffset) end
    if shadowOffset ~= nil and shadowOffset.x == 0 and shadowOffset.y == 0 then shadowOffset = nil end
    if type(strokeSize) ~= "number" then strokeSize = 0 end
    if shadowOffset == nil and strokeSize <= 0 then
        return nil
    end


    local extWidth = 0
    local extHeight = 0
    if shadowOffset ~= nil then
        extWidth = extWidth + math.abs(shadowOffset.x)
        extHeight = extHeight + math.abs(shadowOffset.y)
        if shadowColor == nil then shadowColor = display.COLOR_BLACK end
        if type(shadowOpacity) ~= "number" then shadowOpacity = 255 end
    end
    if strokeSize > 0 then
        extWidth = extWidth + strokeSize
        extHeight = extHeight + strokeSize
        if strokeColor == nil then strokeColor = display.COLOR_BLACK end
        if type(strokeOpacity) ~= "number" then strokeOpacity = 255 end
    end


    --local css = sprite:getTexture():getContentSize() --这行对于打包的图片代价太大
    local css = CCSizeMake(sprite:getContentSize().width * sprite:getScaleX(), sprite:getContentSize().height * sprite:getScaleY())
    local rtWidth = css.width + extWidth * 2
    local rtHeight = css.height + extHeight * 2
    if rtWidth < 1 or rtWidth > 2048 or rtHeight < 1 or rtHeight > 2048 then
        return nil
    end
    local rt
    if pixelFormat then
        rt = CCRenderTexture:create(rtWidth, rtHeight, pixelFormat)
    else
        rt = CCRenderTexture:create(rtWidth, rtHeight)
    end
    local originalPos = ccp(sprite:getPosition())
    local originalColor = sprite:getColor()
    originalColor = ccc3(originalColor.r , originalColor.g,  originalColor.b)
    local originalOpacity = sprite:getOpacity()
    local originalBlend = sprite:getBlendFunc()
    local originalVisibility = sprite:isVisible()
    sprite:setVisible(true)
    --ccBlendFunc 
    local bf = ccBlendFunc()
    bf.src = GL_SRC_ALPHA
    bf.dst = GL_ONE
    sprite:setBlendFunc(bf)


    local bottomLeft = ccp(
        css.width * sprite:getAnchorPoint().x + extWidth, 
        css.height * sprite:getAnchorPoint().y + extHeight)
    local positionOffset= ccp(
        css.width * sprite:getAnchorPoint().x - css.width / 2,
        css.height * sprite:getAnchorPoint().y - css.height / 2)
    local position = ccpSub(originalPos, positionOffset)


    rt:begin()
    if shadowOffset ~= nil then
        sprite:setColor(shadowColor)
        sprite:setOpacity(shadowOpacity)
        sprite:setPosition(bottomLeft.x + shadowOffset.x, bottomLeft.y + shadowOffset.y)
        sprite:visit()
    end
    if strokeSize > 0 then
        sprite:setColor(strokeColor)
        sprite:setOpacity(strokeOpacity)
        for i=0, 360, 60 do -- should optimize that for your needs (15 ~ 60)
            sprite:setPosition(
                ccp(bottomLeft.x + math.sin(math.d2r(i)) * strokeSize, bottomLeft.y + math.cos(math.d2r(i)) * strokeSize)
                )
            sprite:visit()
        end
    end
    rt:endToLua()


    sprite:setPosition(originalPos)
    sprite:setColor(originalColor)
    sprite:setOpacity(originalOpacity)
    sprite:setBlendFunc(originalBlend)
    sprite:setVisible(originalVisibility)
    rt:setPosition(position)


    return rt
end
function ui.createShadowStroke(sprite, params)
    local shadowOffset = params.shadowOffset
    local shadowColor = params.shadowColor
    local shadowOpacity = params.shadowOpacity
    local strokeSize = params.strokeSize
    local strokeColor = params.strokeColor
    local strokeOpacity = params.strokeOpacity
    local pixelFormat = params.pixelFormat
    if type(shadowOffset) == "number" then shadowOffset = ccp(shadowOffset, - shadowOffset) end
    if shadowOffset ~= nil and shadowOffset.x == 0 and shadowOffset.y == 0 then shadowOffset = nil end
    if type(strokeSize) ~= "number" then strokeSize = 0 end
    if shadowOffset == nil and strokeSize <= 0 then
        return nil
    end


    local extWidth = 0
    local extHeight = 0
    if shadowOffset ~= nil then
        extWidth = extWidth + math.abs(shadowOffset.x)
        extHeight = extHeight + math.abs(shadowOffset.y)
        if shadowColor == nil then shadowColor = display.COLOR_BLACK end
        if type(shadowOpacity) ~= "number" then shadowOpacity = 255 end
    end
    if strokeSize > 0 then
        extWidth = extWidth + strokeSize
        extHeight = extHeight + strokeSize
        if strokeColor == nil then strokeColor = display.COLOR_BLACK end
        if type(strokeOpacity) ~= "number" then strokeOpacity = 255 end
    end


    --local css = sprite:getTexture():getContentSize() --这行对于打包的图片代价太大
    local css = CCSizeMake(sprite:getContentSize().width * sprite:getScaleX(), sprite:getContentSize().height * sprite:getScaleY())
    local rtWidth = css.width + extWidth * 2
    local rtHeight = css.height + extHeight * 2
    if rtWidth < 1 or rtWidth > 2048 or rtHeight < 1 or rtHeight > 2048 then
        return nil
    end
    local rt
    if pixelFormat then
        rt = CCRenderTexture:create(rtWidth, rtHeight, pixelFormat)
    else
        rt = CCRenderTexture:create(rtWidth, rtHeight)
    end
    local originalPos = ccp(sprite:getPosition())
    local originalColor = sprite:getColor()
    originalColor = ccc3(originalColor.r , originalColor.g,  originalColor.b)
    local originalOpacity = sprite:getOpacity()
    local originalBlend = sprite:getBlendFunc()
    local originalVisibility = sprite:isVisible()
    sprite:setVisible(true)
    --ccBlendFunc 
    local bf = ccBlendFunc()
    bf.src = GL_SRC_ALPHA
    bf.dst = GL_ONE
    sprite:setBlendFunc(bf)


    local bottomLeft = ccp(
        css.width * sprite:getAnchorPoint().x + extWidth, 
        css.height * sprite:getAnchorPoint().y + extHeight)
    local positionOffset= ccp(
        css.width * sprite:getAnchorPoint().x - css.width / 2,
        css.height * sprite:getAnchorPoint().y - css.height / 2)
    local position = ccpSub(originalPos, positionOffset)


    rt:begin()
    if shadowOffset ~= nil then
        sprite:setColor(shadowColor)
        sprite:setOpacity(shadowOpacity)
        sprite:setPosition(bottomLeft.x + shadowOffset.x, bottomLeft.y + shadowOffset.y)
        sprite:visit()
    end
    if strokeSize > 0 then
        sprite:setColor(strokeColor)
        sprite:setOpacity(strokeOpacity)
        for i=0, 360, 60 do -- should optimize that for your needs (15 ~ 60)
            sprite:setPosition(
                ccp(bottomLeft.x + math.sin(math.d2r(i)) * strokeSize, bottomLeft.y + math.cos(math.d2r(i)) * strokeSize)
                )
            sprite:visit()
        end
    end
    rt:endToLua()


    sprite:setPosition(originalPos)
    sprite:setColor(originalColor)
    sprite:setOpacity(originalOpacity)
    sprite:setBlendFunc(originalBlend)
    sprite:setVisible(originalVisibility)
    rt:setPosition(position)


    return rt
end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值