59 lines
2.5 KiB
TypeScript
59 lines
2.5 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 {
|
|
this.refreshGeometry();
|
|
}
|
|
|
|
/** C 方案按整块形状调整遮罩后,重新计算循环的离场位置。 */
|
|
refreshGeometry(): 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;
|
|
}
|
|
});
|
|
}
|
|
}
|