Cocos2d Label实现颜色渐变

作者: 90d81be3ec65 | 来源:发表于2018-02-27 16:46 被阅读72次

    先看效果图:


    color_gradient.png

    1、ccLabel.h中定义渐变颜色变量

        LabelEffect _currLabelEffect;
        Color4F _effectColorF;
        Color4B _textColor;
        Color4F _textColorF;
        // Added by Blue. 2018.02.24
        Color4B _gradientColor;
    

    2、ccLabel.cpp初始化变量为黑色。后面用来判断是否为初始化颜色进行相关操作,取黑色是因为实现中不可能将字体从某种颜色渐变到黑色,那样不美观

        _effectColorF = Color4F::BLACK;
        _textColor = Color4B::WHITE;
        _textColorF = Color4F::WHITE;
        // Added by Blue. 2018.02.24
        _gradientColor = Color4B::BLACK;
    

    3、给label增加接口设置渐变颜色,该函数将渐变颜色赋值给_gradientColor,并将_contentDirty置为true,表示label属性有变化,在外部调用visit()函数进行渲染的时候,会调用updateContent()更新属性包括颜色

    // Added by Blue. 2018.02.24
    void Label::setGradientColor(const Color4B &color)
    {
        CCASSERT(_currentLabelType == LabelType::TTF || _currentLabelType == LabelType::STRING_TEXTURE, "Only supported system font and ttf!");
    
        if (_currentLabelType == LabelType::STRING_TEXTURE && _textColor != color)
        {
            _contentDirty = true;
        }
    
        _gradientColor = color;
    }
    
    void Label::visit(Renderer *renderer, const Mat4 &parentTransform, uint32_t parentFlags)
    {
        if (! _visible || (_utf8Text.empty() && _children.empty()) )
        {
            return;
        }
        
        if (_systemFontDirty || _contentDirty)
        {
            updateContent();
        }
        
        uint32_t flags = processParentFlags(parentTransform, parentFlags);
    
        if (!_utf8Text.empty() && _shadowEnabled && (_shadowDirty || (flags & FLAGS_DIRTY_MASK)))
        {
            _position.x += _shadowOffset.width;
            _position.y += _shadowOffset.height;
            _transformDirty = _inverseDirty = true;
    
            _shadowTransform = transform(parentTransform);
    
            _position.x -= _shadowOffset.width;
            _position.y -= _shadowOffset.height;
            _transformDirty = _inverseDirty = true;
    
            _shadowDirty = false;
        }
    
        bool visibleByCamera = isVisitableByVisitingCamera();
        if (_children.empty() && !_textSprite && !visibleByCamera)
        {
            return;
        }
    
        // IMPORTANT:
        // To ease the migration to v3.0, we still support the Mat4 stack,
        // but it is deprecated and your code should not rely on it
        _director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
        _director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
        
        if (!_children.empty())
        {
            sortAllChildren();
    
            int i = 0;
            // draw children zOrder < 0
            for (; i < _children.size(); i++)
            {
                auto node = _children.at(i);
    
                if (node && node->getLocalZOrder() < 0)
                    node->visit(renderer, _modelViewTransform, flags);
                else
                    break;
            }
            
            this->drawSelf(visibleByCamera, renderer, flags);
    
            for (auto it = _children.cbegin() + i; it != _children.cend(); ++it)
            {
                (*it)->visit(renderer, _modelViewTransform, flags);
            }
                
        }
        else
        {
            this->drawSelf(visibleByCamera, renderer, flags);
        }
    
        _director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    }
    

    4、在updateColor函数中判断_gradientColor == Color4B::BLACK是否相等(==和!=在结构体Color4B有接口可直接使用)来决定是否对bl.colors,br.colors设置为_gradientColor,这里bl,br分别表示bottomleft,bottomright,颜色自上而下往_gradientColor变化

    // Added by Blue. 2018.02.24
    void Label::updateColor()
    {
        if (_batchNodes.empty())
        {
            return;
        }
    
        Color4B color4( _displayedColor.r, _displayedColor.g, _displayedColor.b, _displayedOpacity );
    
        // special opacity for premultiplied textures
        if (_isOpacityModifyRGB)
        {
            color4.r *= _displayedOpacity/255.0f;
            color4.g *= _displayedOpacity/255.0f;
            color4.b *= _displayedOpacity/255.0f;
        }
    
        // Comment by liudibo. 2018.02.08
        // RGBA batch node need update opacity here, do not ignore update quad here.
        
        cocos2d::TextureAtlas* textureAtlas;
        V3F_C4B_T2F_Quad *quads;
        for (auto&& batchNode:_batchNodes)
        {
            textureAtlas = batchNode->getTextureAtlas();
            quads = textureAtlas->getQuads();
            auto count = textureAtlas->getTotalQuads();
            
            for (int index = 0; index < count; ++index)
            {
                // Added by Blue. 2018.02.24
                if (_gradientColor != Color4B::BLACK) {
                    quads[index].bl.colors = _gradientColor;
                    quads[index].br.colors = _gradientColor;
                } else {
                    quads[index].bl.colors = color4;
                    quads[index].br.colors = color4;
                }
                
                quads[index].tl.colors = color4;
                quads[index].tr.colors = color4;
                textureAtlas->updateQuad(&quads[index], index);
            }
        }
    }
    

    5、如果游戏用lua脚本写的话,那么运行cocos2d提供的genbindings.py脚本,会自动导出接口给lua,genbindings.py运行需要配置环境,这里不进行说明;当然,如果你懂lua c api的话也可以在lua_cocos2dx_auto.cpp下手动写导出函数。在lua_register_cocos2dx_Label方法下添加tolua_function(tolua_S,"setGradientColor",lua_cocos2dx_Label_setGradientColor),然后实现这个方法

    int lua_register_cocos2dx_Label(lua_State* tolua_S)
    {
        tolua_usertype(tolua_S,"cc.Label");
        tolua_cclass(tolua_S,"Label","cc.Label","cc.Node",nullptr);
    
        tolua_beginmodule(tolua_S,"Label");
            tolua_function(tolua_S,"isClipMarginEnabled",lua_cocos2dx_Label_isClipMarginEnabled);
            tolua_function(tolua_S,"enableShadow",lua_cocos2dx_Label_enableShadow);
            tolua_function(tolua_S,"setDimensions",lua_cocos2dx_Label_setDimensions);
            tolua_function(tolua_S,"getWidth",lua_cocos2dx_Label_getWidth);
            tolua_function(tolua_S,"getString",lua_cocos2dx_Label_getString);
            tolua_function(tolua_S,"getHeight",lua_cocos2dx_Label_getHeight);
            tolua_function(tolua_S,"disableEffect",lua_cocos2dx_Label_disableEffect);
            tolua_function(tolua_S,"setTTFConfig",lua_cocos2dx_Label_setTTFConfig);
            tolua_function(tolua_S,"getTextColor",lua_cocos2dx_Label_getTextColor);
            tolua_function(tolua_S,"getBlendFunc",lua_cocos2dx_Label_getBlendFunc);
            tolua_function(tolua_S,"enableWrap",lua_cocos2dx_Label_enableWrap);
            tolua_function(tolua_S,"setWidth",lua_cocos2dx_Label_setWidth);
            tolua_function(tolua_S,"getAdditionalKerning",lua_cocos2dx_Label_getAdditionalKerning);
            tolua_function(tolua_S,"getBMFontSize",lua_cocos2dx_Label_getBMFontSize);
            tolua_function(tolua_S,"getMaxLineWidth",lua_cocos2dx_Label_getMaxLineWidth);
            tolua_function(tolua_S,"getHorizontalAlignment",lua_cocos2dx_Label_getHorizontalAlignment);
            tolua_function(tolua_S,"getShadowOffset",lua_cocos2dx_Label_getShadowOffset);
            tolua_function(tolua_S,"getLineSpacing",lua_cocos2dx_Label_getLineSpacing);
            tolua_function(tolua_S,"setClipMarginEnabled",lua_cocos2dx_Label_setClipMarginEnabled);
            tolua_function(tolua_S,"setString",lua_cocos2dx_Label_setString);
            tolua_function(tolua_S,"setSystemFontName",lua_cocos2dx_Label_setSystemFontName);
            tolua_function(tolua_S,"isWrapEnabled",lua_cocos2dx_Label_isWrapEnabled);
            tolua_function(tolua_S,"getOutlineSize",lua_cocos2dx_Label_getOutlineSize);
            tolua_function(tolua_S,"setBMFontFilePath",lua_cocos2dx_Label_setBMFontFilePath);
            tolua_function(tolua_S,"initWithTTF",lua_cocos2dx_Label_initWithTTF);
            tolua_function(tolua_S,"getFontAtlas",lua_cocos2dx_Label_getFontAtlas);
            tolua_function(tolua_S,"setLineHeight",lua_cocos2dx_Label_setLineHeight);
            tolua_function(tolua_S,"setSystemFontSize",lua_cocos2dx_Label_setSystemFontSize);
            tolua_function(tolua_S,"setOverflow",lua_cocos2dx_Label_setOverflow);
            tolua_function(tolua_S,"enableStrikethrough",lua_cocos2dx_Label_enableStrikethrough);
            tolua_function(tolua_S,"updateContent",lua_cocos2dx_Label_updateContent);
            tolua_function(tolua_S,"getStringLength",lua_cocos2dx_Label_getStringLength);
            tolua_function(tolua_S,"setLineBreakWithoutSpace",lua_cocos2dx_Label_setLineBreakWithoutSpace);
            tolua_function(tolua_S,"getStringNumLines",lua_cocos2dx_Label_getStringNumLines);
            tolua_function(tolua_S,"enableOutline",lua_cocos2dx_Label_enableOutline);
            tolua_function(tolua_S,"getShadowBlurRadius",lua_cocos2dx_Label_getShadowBlurRadius);
            tolua_function(tolua_S,"getEffectColor",lua_cocos2dx_Label_getEffectColor);
            tolua_function(tolua_S,"removeAllChildrenWithCleanup",lua_cocos2dx_Label_removeAllChildrenWithCleanup);
            tolua_function(tolua_S,"setCharMap",lua_cocos2dx_Label_setCharMap);
            tolua_function(tolua_S,"getDimensions",lua_cocos2dx_Label_getDimensions);
            tolua_function(tolua_S,"setMaxLineWidth",lua_cocos2dx_Label_setMaxLineWidth);
            tolua_function(tolua_S,"getSystemFontName",lua_cocos2dx_Label_getSystemFontName);
            tolua_function(tolua_S,"setVerticalAlignment",lua_cocos2dx_Label_setVerticalAlignment);
            tolua_function(tolua_S,"setLineSpacing",lua_cocos2dx_Label_setLineSpacing);
            tolua_function(tolua_S,"getLineHeight",lua_cocos2dx_Label_getLineHeight);
            tolua_function(tolua_S,"getShadowColor",lua_cocos2dx_Label_getShadowColor);
            tolua_function(tolua_S,"getTTFConfig",lua_cocos2dx_Label_getTTFConfig);
            tolua_function(tolua_S,"enableItalics",lua_cocos2dx_Label_enableItalics);
            tolua_function(tolua_S,"setTextColor",lua_cocos2dx_Label_setTextColor);
            tolua_function(tolua_S,"getLetter",lua_cocos2dx_Label_getLetter);
            tolua_function(tolua_S,"setHeight",lua_cocos2dx_Label_setHeight);
            tolua_function(tolua_S,"isShadowEnabled",lua_cocos2dx_Label_isShadowEnabled);
            tolua_function(tolua_S,"enableGlow",lua_cocos2dx_Label_enableGlow);
            tolua_function(tolua_S,"getOverflow",lua_cocos2dx_Label_getOverflow);
            tolua_function(tolua_S,"getVerticalAlignment",lua_cocos2dx_Label_getVerticalAlignment);
            tolua_function(tolua_S,"setAdditionalKerning",lua_cocos2dx_Label_setAdditionalKerning);
            tolua_function(tolua_S,"getSystemFontSize",lua_cocos2dx_Label_getSystemFontSize);
            tolua_function(tolua_S,"setBlendFunc",lua_cocos2dx_Label_setBlendFunc);
            tolua_function(tolua_S,"getTextAlignment",lua_cocos2dx_Label_getTextAlignment);
            tolua_function(tolua_S,"getBMFontFilePath",lua_cocos2dx_Label_getBMFontFilePath);
            tolua_function(tolua_S,"setHorizontalAlignment",lua_cocos2dx_Label_setHorizontalAlignment);
            tolua_function(tolua_S,"enableBold",lua_cocos2dx_Label_enableBold);
            tolua_function(tolua_S,"enableUnderline",lua_cocos2dx_Label_enableUnderline);
            tolua_function(tolua_S,"getLabelEffectType",lua_cocos2dx_Label_getLabelEffectType);
            tolua_function(tolua_S,"setAlignment",lua_cocos2dx_Label_setAlignment);
            tolua_function(tolua_S,"requestSystemFontRefresh",lua_cocos2dx_Label_requestSystemFontRefresh);
            tolua_function(tolua_S,"setGradientColor",lua_cocos2dx_Label_setGradientColor);
            tolua_function(tolua_S,"setBMFontSize",lua_cocos2dx_Label_setBMFontSize);
            tolua_function(tolua_S,"createWithBMFont", lua_cocos2dx_Label_createWithBMFont);
            tolua_function(tolua_S,"create", lua_cocos2dx_Label_create);
            tolua_function(tolua_S,"createWithCharMap", lua_cocos2dx_Label_createWithCharMap);
            tolua_function(tolua_S,"createWithSystemFont", lua_cocos2dx_Label_createWithSystemFont);
        tolua_endmodule(tolua_S);
        std::string typeName = typeid(cocos2d::Label).name();
        g_luaType[typeName] = "cc.Label";
        g_typeCast["Label"] = "cc.Label";
        return 1;
    }
    
    int lua_cocos2dx_Label_setGradientColor(lua_State* tolua_S)
    {
        int argc = 0;
        cocos2d::Label* cobj = nullptr;
        bool ok  = true;
    
    #if COCOS2D_DEBUG >= 1
        tolua_Error tolua_err;
    #endif
    
    
    #if COCOS2D_DEBUG >= 1
        if (!tolua_isusertype(tolua_S,1,"cc.Label",0,&tolua_err)) goto tolua_lerror;
    #endif
    
        cobj = (cocos2d::Label*)tolua_tousertype(tolua_S,1,0);
    
    #if COCOS2D_DEBUG >= 1
        if (!cobj) 
        {
            tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_Label_setGradientColor'", nullptr);
            return 0;
        }
    #endif
    
        argc = lua_gettop(tolua_S)-1;
        if (argc == 1) 
        {
            cocos2d::Color4B arg0;
    
            ok &=luaval_to_color4b(tolua_S, 2, &arg0, "cc.Label:setGradientColor");
            if(!ok)
            {
                tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_Label_setGradientColor'", nullptr);
                return 0;
            }
            cobj->setGradientColor(arg0);
            lua_settop(tolua_S, 1);
            return 1;
        }
        luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.Label:setGradientColor",argc, 1);
        return 0;
    
    #if COCOS2D_DEBUG >= 1
        tolua_lerror:
        tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_Label_setGradientColor'.",&tolua_err);
    #endif
    
        return 0;
    }
    

    6、lua下调用label:setGradientColor({r = 60, g = 160, b = 220}),原始颜色自上而下渐变为设定颜色

    相关文章

      网友评论

        本文标题:Cocos2d Label实现颜色渐变

        本文链接:https://www.haomeiwen.com/subject/ialmxftx.html