cocoscreator用shader实现游戏中被攻击的闪白效果

1,302 阅读1分钟

先看效果

dr6kj-u3jix.gif

原理

在着色器上,对每个像素点进行颜色混合,这里要展示闪白效果,就让每个像素的R、G、B都要乘于255.0,由于和纯白色混合后的效果,会接近纯白,因此我们这里取5.0代替255.0

gl_FragColor = vec4(o.rgba.r*5.0, o.rgba.g*5.0, o.rgba.b*5.0, o.rgba.a);

当然如果要实现闪其他颜色,可以乘于对应颜色的颜色值,如红色,R需要乘于255.0,G和B只要乘以0.0

gl_FragColor = vec4(o.rgba.r * 255.0, o.rgba.g * 0.0, o.rgba.b * 0.0, o.rgba.a);

修改材质

这里以spine和sprite为例,因此我们直接复制内置effect来修改,spine和sprite内置的effect分别是builtin-2d-spine和builtin-2d-sprite这两个文件。

修改后的sprite effect文件

void main () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
      CCTexture(texture, v_uv0, o);
    #endif

    o *= v_color;

    ALPHA_TEST(o);

    #if USE_BGRA
      // 修改前
      // gl_FragColor = o.bgra;
      
      // 修改后
      gl_FragColor = vec4(o.bgra.r*5.0, o.bgra.g*5.0, o.bgra.b*5.0, o.bgra.a);
    #else
      // 修改前
      // gl_FragColor = o.rgba;
      
      // 修改后
      gl_FragColor = vec4(o.rgba.r*5.0, o.rgba.g*5.0, o.rgba.b*5.0, o.rgba.a);
    #endif
  }

修改后的spine effect文件

void main () {
  vec4 texColor = vec4(1.0);
  CCTexture(texture, v_uv0, texColor);
  vec4 finalColor;

  #if USE_TINT
    finalColor.a = v_light.a * texColor.a;
    finalColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;
  #else
    finalColor = texColor * v_light;
  #endif

  ALPHA_TEST(finalColor);
  
  // 修改前
  // gl_FragColor = finalColor;
  
  // 修改后
  gl_FragColor = vec4(finalColor.r * 5.0, finalColor.g * 5.0, finalColor.b * 5.0, finalColor.a);
}

实现

点击spine或者sprite的时候,切换成闪白材质,0.1秒切回普通材质,即实现效果,代码如下:

const { ccclass, property } = cc._decorator;

@ccclass
export default class AttackBlink extends cc.Component {

    /** 恐龙spine */
    @property(sp.Skeleton)
    spine: sp.Skeleton = null;

    /** 精灵图片 */
    @property(cc.Sprite)
    img: cc.Sprite = null;

    /** 普通图片材质 */
    @property(cc.Material)
    normalMaterial: cc.Material = null;

    /** 被攻击图片材质 */
    @property(cc.Material)
    attackedMaterial: cc.Material = null;

    /** 普通spine材质 */
    @property(cc.Material)
    normalSpineMaterial: cc.Material = null;

    /** 被攻击spine材质 */
    @property(cc.Material)
    attackedSpineMaterial: cc.Material = null;

    onLoad() {
        // 监听精灵图片点击
        this.img.node.on(cc.Node.EventType.TOUCH_END, this.onImgTouchEnd, this);
        // 监听恐龙spine点击
        this.spine.node.on(cc.Node.EventType.TOUCH_END, this.onSpineTouchEnd, this);
    }

    onImgTouchEnd() {
        // 精灵图片切换成被攻击的闪白材质
        this.img.setMaterial(0, this.attackedMaterial);
        // 0.1秒后切换回普通材质
        this.scheduleOnce(this.switchNormalMaterial, 0.1);
    }

    switchNormalMaterial() {
        // 切换成普通材质
        this.img.setMaterial(0, this.normalMaterial);
    }

    onSpineTouchEnd() {
        // 恐龙spine切换成被攻击的闪白材质
        this.spine.setMaterial(0, this.attackedSpineMaterial);
        // 0.1秒后切换回普通材质
        this.scheduleOnce(this.switchNormalSpineMaterial, 0.1);
    }

    switchNormalSpineMaterial() {
        // 切换成普通spine材质
        this.spine.setMaterial(0, this.normalSpineMaterial);
    }
}