<二>粒子跟随(矩形)进度条效果
import { _decorator, Component, Intersection2D, math, Node, Rect, rect, Sprite, tween, UITransform, v2 } from 'cc';
const { ccclass, property } = _decorator;
interface Point {
x: number;
y: number;
}
@ccclass('Test')
export class Test extends Component {
@property(Node)
test_sprite: Node = null;
@property(Node)
test_particle: Node = null;
@property
speed:number = 1;
progress_angle = 0;
start_ani:boolean = false;
start() {
this.startLight();
}
startLight(){
this.start_ani = true;
}
updatePaticle(){
//计算当前进度角度对应的射线与test_sprite矩形框边缘的交点
let rect = new math.Rect();
rect.x = -this.test_sprite.getComponent(UITransform).width * 0.5;
rect.y = -this.test_sprite.getComponent(UITransform).height * 0.5;
rect.width = this.test_sprite.getComponent(UITransform).width;
rect.height = this.test_sprite.getComponent(UITransform).height;
let radias = Math.sqrt(rect.width * rect.width + rect.height * rect.height) / 2;
console.log('r = ' + radias);
let angle = this.progress_angle * Math.PI / 180;
let x = radias * Math.cos(angle);
let y = radias * Math.sin(angle);
//计算线段v2(0,0), v2(x,y)与rect矩形框的交点
let start_p:Point = {x:0, y:0};
let end_p:Point = {x:x, y:y};
let result = this.intersection(start_p, end_p, rect);
this.test_particle.setPosition(result[0].x, result[0].y, 0);
}
update(deltaTime: number) {
if(!this.start_ani)return;
if(this.progress_angle >= 360)return;
this.progress_angle += this.speed * deltaTime;
if(this.progress_angle >= 360){
this.progress_angle = 360;
}
let sprite_per = this.progress_angle / 360;
this.test_sprite.getComponent(Sprite).fillRange = sprite_per;
this.updatePaticle();
}
intersection(lineStart: Point, lineEnd: Point, rect: Rect): Point[] {
const intersections: Point[] = [];
// 矩形的四条边
const edges = [
{ start: { x: rect.x, y: rect.y }, end: { x: rect.x + rect.width, y: rect.y } }, // 上边
{ start: { x: rect.x + rect.width, y: rect.y }, end: { x: rect.x + rect.width, y: rect.y + rect.height } }, // 右边
{ start: { x: rect.x + rect.width, y: rect.y + rect.height }, end: { x: rect.x, y: rect.y + rect.height } }, // 下边
{ start: { x: rect.x, y: rect.y + rect.height }, end: { x: rect.x, y: rect.y } } // 左边
];
for (const edge of edges) {
const intersectionPoint = this.getIntersection(lineStart, lineEnd, edge.start, edge.end);
if (intersectionPoint) {
intersections.push(intersectionPoint);
}
}
return intersections;
}
getIntersection(p1: Point, p2: Point, q1: Point, q2: Point): Point | null {
const denominator = (p2.y - p1.y) * (q2.x - q1.x) - (p2.x - p1.x) * (q2.y - q1.y);
if (denominator === 0) {
return null; // 线段平行或共线
}
const t = ((p1.x - q1.x) * (q2.y - q1.y) - (p1.y - q1.y) * (q2.x - q1.x)) / denominator;
const u = -((p2.x - p1.x) * (p1.y - q1.y) - (p2.y - p1.y) * (p1.x - q1.x)) / denominator;
if (t >= 0 && t <= 1 && u >= 0 && u <= 1) {
return {
x: p1.x + t * (p2.x - p1.x),
y: p1.y + t * (p2.y - p1.y)
};
}
return null; // 交点不在线段上
}
}
浙公网安备 33010602011771号