import { _decorator, BoxCollider2D, CCBoolean, CircleCollider2D, Collider2D, Color, Node, Component, Contact2DType, Input, IPhysics2DContact, PhysicsSystem2D, PolygonCollider2D, RigidBody2D, Sprite, Rect, Enum, HingeJoint2D, Vec2 } from 'cc'; import { CarColorHex, CarColorLog, CarColors } from '../CarColorsGlobalTypes'; import { HoleComponent } from './HoleComponent'; import { LayerAction } from '../LayerAction'; import { UnitAction } from '../UnitAction'; import { GameUtil } from '../GameUtil'; const { ccclass, property, executeInEditMode } = _decorator; /** 钉子组件*/ @ccclass('PinComponent') @executeInEditMode export class PinComponent extends Component { @property({ type: Enum(CarColors) }) get pin_color() { return this._pin_color } set pin_color(value) { this._pin_color = value this.changeColor() } @property({ type: Enum(CarColors) }) private _pin_color: CarColors = CarColors.Purple isBlocked: boolean = false; isProcessing: boolean = false; pos_hole: HoleComponent = null; start() { // this.checkBlocking(); } // 获取当前 pin 所属的 layer 节点 private getParentLayer(node: Node): Node | null { let current = node.parent; while (current) { if (current.parent?.getComponent(UnitAction)) { return current; } current = current.parent!; } return null; } // 获取当前层以上的所有 layer private getHigherLayers(currentLayer: Node): Node[] { const higherLayers: Node[] = []; const unitNode = currentLayer.parent; // 当前 layer 的父节点是 unit if (!unitNode) return higherLayers; // 获取当前 layer 的索引 const currentLayerIndex = this.getLayerIndex(currentLayer.name); if (isNaN(currentLayerIndex)) return higherLayers; // 遍历 unit 下的所有 layer,找到比当前层高的 layer unitNode.children.forEach((layer) => { const layerIndex = this.getLayerIndex(layer.name); if (!isNaN(layerIndex) && layerIndex > currentLayerIndex) { higherLayers.push(layer); } }); return higherLayers; } // 从 layer 名称中提取索引 private getLayerIndex(layerName: string): number { const match = layerName.match(/layer_(\d+)/); return match ? parseInt(match[1], 10) : NaN; } // 获取当前 pin 的包围盒 private getWorldBoundingBox(): Rect | null { const collider = this.node.getComponent(CircleCollider2D); if (!collider) return null; const aabb = collider.worldAABB; return new Rect(aabb.xMin, aabb.yMin, aabb.width, aabb.height); } // 检查是否被遮挡 checkBlocking() { const circleCollider2D = this.node.getComponent(CircleCollider2D); if (!circleCollider2D) { // console.error('钉子节点缺少 CircleCollider2D 组件'); return; } // 获取当前 pin 所在的 layer const currentLayer = this.getParentLayer(this.node); if (!currentLayer) { console.warn('无法获取当前钉子所在的 layer'); return; } // 获取当前层以上的所有 layer const higherLayers = this.getHigherLayers(currentLayer); if (higherLayers.length === 0) { // this.isBlocked = false; // 没有上层 layer,钉子未被阻挡 return; } // 检测钉子是否与上层 layer 中的 element 节点碰撞体相交 this.isBlocked = higherLayers.some((layer) => { const elements = layer.getComponentsInChildren(PolygonCollider2D); return elements.some((elementCollider) => { return GameUtil.isPolygonAndCircleIntersecting(elementCollider, circleCollider2D); }); }); // console.log('钉子颜色:', CarColorLog[this.pin_color], '是否被阻挡:', this.isBlocked); if (this.isBlocked) { // console.log(`${CarColorLog[this.pin_color]} 被遮挡了`); } else { // console.log(`${CarColorLog[this.pin_color]} 未被遮挡了, 可以溜`); } } public init_date(group_id: number, pin_color: CarColors, hole: HoleComponent) { this.pos_hole = hole; this.node.getComponent(RigidBody2D).group = group_id; this._pin_color = pin_color; //set color this.reset_img(); } reset_img() { if (!this._pin_color) { console.log(`被return的颜色${this._pin_color}`); return; } this.changeColor(); // this.pin_img.getComponent(Sprite).color = new Color().fromHEX(CarColorHex[this.pin_color]); } changeColor() { this.node.children.forEach(child => { if (child.name === CarColors[this._pin_color]) { child.active = true } else { child.active = false } }) } protected onDestroy(): void { } }