Cocos2d-X与游戏开发cocos2d-x

Cocos2d Label实现颜色渐变

2018-02-27  本文已影响72人  90d81be3ec65

先看效果图:


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}),原始颜色自上而下渐变为设定颜色

上一篇下一篇

猜你喜欢

热点阅读