<二>粒子跟随(矩形)进度条效果

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; // 交点不在线段上
}

}

posted @ 2025-03-14 19:16  EricShx  阅读(7)  评论(0)    收藏  举报