MatchMaster/assets/shop/script/ShopTitleShine.ts

91 lines
3.2 KiB
TypeScript

const { ccclass, property, requireComponent } = cc._decorator;
/** 挂到带 Sprite 的节点上,并在 Inspector 中指定 svip_title_shine.effect。 */
@ccclass
@requireComponent(cc.Sprite)
export default class ShopTitleShine extends cc.Component {
@property(cc.EffectAsset)
effectAsset: cc.EffectAsset = null;
@property({ tooltip: '使用彩虹色扫光' })
rainbow: boolean = false;
private material: cc.Material = null;
private sprite: cc.Sprite = null;
private frame: cc.SpriteFrame = null;
private delayRemaining: number = 0.15;
private elapsed: number = 0;
protected onLoad(): void {
this.sprite = this.getComponent(cc.Sprite);
if (this.effectAsset) {
this.createMaterial();
} else {
cc.assetManager.getBundle('shop').load('effect/svip_title_shine', cc.EffectAsset, (error, effect: cc.EffectAsset) => {
if (error || !cc.isValid(this.node)) return;
this.effectAsset = effect;
this.createMaterial();
});
}
}
private createMaterial(): void {
let material = new cc.Material();
// @ts-ignore Cocos Creator 2.4 通过 effectAsset 创建运行时材质。
material.effectAsset = this.effectAsset;
material.setProperty("shinePosition", -0.2);
material.setProperty("shineAngle", 0.2);
material.setProperty("shineColor", [1.0, 0.95, 0.68, 1.0]);
this.material = material;
this.setRainbow(this.rainbow);
this.updateFrame();
this.sprite.setMaterial(0, material);
}
setRainbow(enabled: boolean): void {
this.rainbow = enabled;
if (!this.material) return;
this.material.setProperty('rainbow', enabled ? 1 : 0);
this.material.setProperty('shineWidth', enabled ? 0.10 : 0.06);
this.material.setProperty('shineStrength', enabled ? 1.6 : 1.2);
}
private updateFrame(): void {
const frame = this.sprite.spriteFrame;
if (!frame || frame === this.frame) return;
this.frame = frame;
const rect = frame.getRect(), texture = frame.getTexture(), rotated = frame.isRotated();
texture.packable = false;
this.material.setProperty('uvRect', [rect.x / texture.width, rect.y / texture.height,
(rotated ? rect.height : rect.width) / texture.width, (rotated ? rect.width : rect.height) / texture.height]);
this.material.setProperty('uvRotated', rotated ? 1 : 0);
}
protected update(dt: number): void {
if (!this.material) {
return;
}
this.updateFrame();
if (this.delayRemaining > 0) {
this.delayRemaining = Math.max(0, this.delayRemaining - dt);
return;
}
this.elapsed += dt;
let progress = Math.min(1, this.elapsed / 0.8);
this.material.setProperty("shinePosition", -0.2 + 1.4 * progress);
if (progress >= 1) {
this.elapsed = 0;
this.delayRemaining = 1.25;
this.material.setProperty("shinePosition", -0.2);
}
}
protected onDestroy(): void {
if (this.material && cc.isValid(this.material)) {
this.material.destroy();
}
this.material = null;
}
}