MatchMaster/assets/Script/prop/RainbowScroll.ts
WIN-GKKD951VVMJ\Administrator 2029441aae 更新迭代动画效果
2026-09-15 18:31:24 +08:00

54 lines
2.4 KiB
TypeScript

const { ccclass, property } = cc._decorator;
/** 两张镜像彩虹沿旋转后的纵轴循环,完全离开遮罩后接到另一张后面。 */
@ccclass
export default class RainbowScroll extends cc.Component {
@property(cc.Node)
color1: cc.Node = null;
@property(cc.Node)
color2: cc.Node = null;
@property({ tooltip: "彩虹向左上滚动的速度(每秒像素)", min: 0 })
speed: number = 60;
private colors: cc.Node[] = [];
private direction = cc.v2(0, 0);
private exits: number[] = [];
private loopLength = 0;
onLoad(): void {
// 预制体重存后引用可能为空,按既有节点层级恢复。
const mask = this.node.getChildByName("mask");
this.color1 = this.color1 || mask.getChildByName("color1");
this.color2 = this.color2 || mask.getChildByName("color2");
this.colors = [this.color1, this.color2];
const radians = this.color1.angle * Math.PI / 180;
this.direction = cc.v2(-Math.sin(radians), Math.cos(radians));
const centers = this.colors.map(node => mask.convertToNodeSpaceAR(node.convertToWorldSpaceAR(
cc.v2((0.5 - node.anchorX) * node.width, (0.5 - node.anchorY) * node.height))));
const offsets = centers.map((center, i) => cc.v2(center.x - this.colors[i].x, center.y - this.colors[i].y));
const lengths = this.colors.map(node => node.height * Math.abs(node.scaleY));
this.loopLength = lengths[0] + lengths[1];
const left = -mask.width * mask.anchorX;
const bottom = -mask.height * mask.anchorY;
const maskEnd = Math.max(left * this.direction.x, (left + mask.width) * this.direction.x)
+ Math.max(bottom * this.direction.y, (bottom + mask.height) * this.direction.y);
this.exits = offsets.map((offset, i) => maskEnd + lengths[i] / 2
- offset.x * this.direction.x - offset.y * this.direction.y);
}
update(dt: number): void {
const distance = (this.speed * dt) % this.loopLength;
this.colors.forEach((node, i) => {
node.x += this.direction.x * distance;
node.y += this.direction.y * distance;
if (node.x * this.direction.x + node.y * this.direction.y > this.exits[i]) {
node.x -= this.direction.x * this.loopLength;
node.y -= this.direction.y * this.loopLength;
}
});
}
}