[cocos2d-x] 《我所理解的Cocos2d-x》上机实验3-自定义动画——精灵闪白

这个例子做得就比较顺了,基本没遇到什么坎。

顶点着色器:

attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;

#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif

void main()
{
    gl_Position = CC_PMatrix * a_position;
    v_fragmentColor = a_color;
    v_texCoord = a_texCoord;
}

片段着色器:

varying vec4 v_fragmentColor;
varying vec2 v_texCoord;

uniform float u_alpha;
uniform vec4 u_blendColor;

void main(void)
{
    vec4 realColor = texture2D(CC_Texture0, v_texCoord);
    
    if (realColor.a > 0.)
    {
        gl_FragColor = u_blendColor * u_alpha + realColor * (1. - u_alpha);
    }
    else
    {
        discard;
    }
}

BlendAction.h

class BlendAction : public ActionInterval
{
public:
    static BlendAction* create(float flDuring, Color4B blendColor, bool bReverse = false);
    virtual BlendAction* reverse() const override;
    
private:
    bool _reverse = false;
    Color4B _color;
    GLProgramState* _pstate = nullptr;
    float _percent = 0.0f;
    
    bool initWithParas(float flDuring, Color4B blendColor, bool bReverse);
    
    virtual void startWithTarget(Node *target) override;
    virtual void update(float t) override;
    virtual void stop(void) override;
};

BlendAction.cpp

#include "BlendAction.hpp"

// 书中省略的地方
BlendAction* BlendAction::create(float flDuring, Color4B blendColor, bool bReverse)
{
    BlendAction *ret = new (std::nothrow) BlendAction();
    
    if (ret && ret->initWithParas(flDuring, blendColor, bReverse))
       {
           ret->autorelease();
           return ret;
       }
       
       delete ret;
       return nullptr;
}

// 书中省略的地方
bool BlendAction::initWithParas(float flDuring, Color4B blendColor, bool bReverse)
{
    if (initWithDuration(flDuring) == false)
    {
        return false;
    }
    
    _color = blendColor;
    _reverse = bReverse;
    
    return true;
}

void BlendAction::startWithTarget(Node *target)
{
    ActionInterval::startWithTarget(target);
    
    _pstate = target->getGLProgramState();
    _pstate->retain();
    
    auto program = GLProgram::createWithFilenames("res/ccShader_PositionTextureColor_noMVP.vert", "res/blend_color.frag");
    auto pstate = GLProgramState::create(program);
    target->setGLProgramState(pstate);
        
    pstate->setUniformCallback("u_alpha", [this](GLProgram* p, Uniform* u)
                               {
        p->setUniformLocationWith1f(u->location, _percent);
    });
    
    auto blendColor = Vec4(_color.r / 255.0, _color.g / 255.0, _color.b / 255.0, _color.a / 255.0);
    pstate->setUniformVec4("u_blendColor", blendColor);
}

void BlendAction::update(float t)
{
    _percent = _reverse ? 1.0 - t : t;
}

void BlendAction::stop(void)
{
    getTarget()->setGLProgramState(_pstate);
    _pstate->autorelease();
}

// 书中省略的地方
BlendAction* BlendAction::reverse() const
{
    return BlendAction::create(_duration, _color, true);
}

在HelloWorldScene.cpp中使用

bool HelloWorld::init()
{
    ... ... // 略掉的原有内容
    auto sprite = Sprite::create("HelloWorld.png");
    sprite->setPosition(_center);
    addChild(sprite, 10);
    
    auto bColor = BlendAction::create(10, Color4B::RED);
    auto rColor = bColor->reverse();
    auto sequence = Sequence::create(bColor, rColor, NULL);
    
    sprite->runAction(Repeat::create(sequence, 100));
    
    return true;
}

最终效果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值