悉野小楼

导航

子弹射击

Bullet.ts
private _lastCheckPos:Laya.Point = new Laya.Point(0, 0); // 上次检测的位置
/**
 * 检查两条线段是否相交 
 * 线段1: (x1, y1) -> (x2, y2)
 * 线段2: (x3, y3) -> (x4, y4)
 */
isLinesIntersect(x1, y1, x2, y2, x3, y3, x4, y4) {
    let denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
    if (denom === 0) {
        return false; // 平行或共线
    }
    let t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / denom;
    let u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / denom;

    return t >= 0 && t <= 1 && u >= 0 && u <= 1;
}

/**
 * 检查子弹是否与怪物矩形相撞
 * @param {Laya.Point} start 子弹起始位置
 * @param {Laya.Point} end 子弹结束位置
 * @param {Laya.Rectangle} rect 怪物矩形
 * @returns {boolean} 如果相撞返回 true,否则返回 false
 */
checkBulletHit(start, end, rect) {
    // 1. 检查线段的两个端点是否在矩形内部
    if (rect.contains(start.x, start.y) || rect.contains(end.x, end.y)) {
        return true;
    }

    // 2. 检查线段是否与矩形的四条边相交
    // 定义矩形的四条边
    let left = rect.x;
    let right = rect.x + rect.width;
    let top = rect.y;
    let bottom = rect.y + rect.height;

    // 定义线段的两个端点
    let x1 = start.x;
    let y1 = start.y;
    let x2 = end.x;
    let y2 = end.y;

    // 检查线段是否与矩形的四条边相交
    // 左边
    if (this.isLinesIntersect(x1, y1, x2, y2, left, top, left, bottom)) return true;
    // 右边
    if (this.isLinesIntersect(x1, y1, x2, y2, right, top, right, bottom)) return true;
    // 上边
    if (this.isLinesIntersect(x1, y1, x2, y2, left, top, right, top)) return true;
    // 下边
    if (this.isLinesIntersect(x1, y1, x2, y2, left, bottom, right, bottom)) return true;

    // 如果都不相交
    return false;
}

/**
 * 检查子弹是否与怪物最近的怪物相撞
 * @returns {boolean} 如果相撞返回 怪物,否则返回 null
 */
checkHit(fishCtrl: FishCtrl): IFish {
    if (this._hasHit) return null;
    if (this._target) return null;

    let nowPos = new Laya.Point(this.x, this.y);
    let fishList = fishCtrl.getFishList();
    let minDistance = Number.MAX_VALUE;
    let targetMonster = null;
    for (let fishId in fishList) {
        let fish: IFish = fishList[fishId];
        let hitRect = fish.getHitRect();
        if (fish && fish.type != 0 && fish.canShoot && this.checkBulletHit(this._lastCheckPos, nowPos, hitRect)) {
               // 计算起点到怪物中心的距离
            let distance = this._lastCheckPos.distance(hitRect.x + hitRect.width / 2, hitRect.y + hitRect.height / 2);
            if (distance < minDistance) {
                minDistance = distance;
                targetMonster = fish;
            }
        }
    }
    this._lastCheckPos = nowPos;
    return targetMonster;
        
}
private _dirction: Vector2;
step(time: number): number {
    let x = this.x + this._dirction.x * s
    let y = this.y + this._dirction.y * s
    this.pos(x, y, true);
}

init(uid: number, id: number, from: Vector2, to: Vector2): void {
    let a: number = to.x - from.x;
    let b: number = to.y - from.y;
    let m: number = Math.sqrt(a * a + b * b);
    this._dirction.x = a / m;
    this._dirction.y = b / m;
    this.pos(from.x, from.y, true);
    this._lastCheckPos = new Laya.Point(from.x, from.y);
}

BulletCtrl.ts
Laya.timer.frameLoop(1, this, this.loop);

private loop() {
    let now: number = getTime();
    for (let i = 0; i < this._bulletList.length; i++) {
        let fish: IFish, fishID: number;
        let b: Bullet = this._bulletList[i];
        
        if (b.hasHit) {
            b.hit();
            this._bulletList.splice(i, 1);
            i = i - 1;

            let count: number = this._bulletCnt[b.uid] || 0;
            this._bulletCnt[b.uid] = --count;
        } else {
            //移动
            fishID = b.step(now - this._lastTime);
        }
        // 检测是否击中
        let fish = b.checkHit(this._fishCtrl);

        if (fish) {
            fishID = fish.id;
            b.hit(); // 处理爆炸
            this._bulletList.splice(i, 1);
            i = i - 1;
            let count: number = this._bulletCnt[b.uid] || 0;
            this._bulletCnt[b.uid] = --count;
        }
        app.event(BulletCtrl.BULLET_HIT_FISH, { isrobot: b.isrobot, uid: b.uid, bullet_id: b.id, fishid: fishID, ls: [] });
    }
    this._lastTime = now;
}

 

posted on 2025-12-05 21:05  悉野  阅读(0)  评论(0)    收藏  举报