import { _decorator, Component, EventTouch, instantiate, Node, Prefab, Slider, tween, Vec2, Vec3 } from 'cc'; const { ccclass, property } = _decorator; // 物品数据类 export class ItemData { position: Vec3 = new Vec3(0, 0, 0); scale: number = 1; } // 物品状态枚举 export enum ItemState { EDIT, // 编辑状态 NORMAL, // 正常状态 FOUND, // 已找到状态 HINT // 提示状态 } @ccclass export default class FindItem extends Component { @property({ type: Node }) spineNode: Node = null; @property({ type: Slider }) scaleSlider: Slider = null; // 缩放滑动条 @property({ type: Node }) redFrame: Node = null; // 红色框 @property({ type: Node }) blueFrame: Node = null; // 蓝色框 // 组件数据 private data: ItemData = { position: new Vec3(0, 0, 0), scale: 1 }; // 当前状态 private currentState: ItemState = ItemState.EDIT; // 拖动相关 private isDragging: boolean = false; // 缩放范围 private readonly MIN_SCALE: number = 0.1; private readonly MAX_SCALE: number = 1.5; onLoad() { this.setupEventListeners(); } start() { this.initializeFromData(); this.setState(this.currentState); } onDestroy() { this.removeEventListeners(); } // 设置事件监听 private setupEventListeners() { this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this); this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this); this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this); this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this); } // 移除事件监听 private removeEventListeners() { this.node.off(Node.EventType.TOUCH_START, this.onTouchStart, this); this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this); this.node.off(Node.EventType.TOUCH_END, this.onTouchEnd, this); this.node.off(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this); } // 根据数据初始化 private initializeFromData() { this.node.setPosition(this.data.position); this.spineNode.setScale(this.data.scale, this.data.scale, 1); if (this.scaleSlider) { const sliderComp = this.scaleSlider.getComponent(Slider); if (sliderComp) { sliderComp.progress = (this.data.scale - this.MIN_SCALE) / (this.MAX_SCALE - this.MIN_SCALE); } } } // 设置状态 public setState(state: ItemState) { this.currentState = state; this.updateVisualState(); } // 更新视觉状态 private updateVisualState() { // 重置所有状态 this.scaleSlider.node.active = false; this.redFrame.active = false; this.blueFrame.active = false; switch (this.currentState) { case ItemState.EDIT: this.scaleSlider.node.active = true; break; case ItemState.NORMAL: // 正常状态,无特殊显示 break; case ItemState.FOUND: this.redFrame.active = true; break; case ItemState.HINT: this.blueFrame.active = true; this.startBlueFrameAnimation(); break; } } // 开始蓝色框动画 private startBlueFrameAnimation() { tween(this.blueFrame) .to(0.5, { scale: new Vec3(1.2, 1.2, 1) }) .to(0.5, { scale: new Vec3(1, 1, 1) }) .repeatForever() .start(); } _touchStartPos: Vec2 = new Vec2(0, 0); _nodeStartPos: Vec3 = new Vec3(0, 0, 0); // 触摸开始 private onTouchStart(event: EventTouch) { const touch = event.touch; if (this.currentState === ItemState.EDIT) { this._touchStartPos = new Vec2(touch.getUILocation().x, touch.getUILocation().y); this._nodeStartPos = this.node.getPosition(); // 编辑状态可以拖动 this.isDragging = true; } else if (this.currentState === ItemState.NORMAL || this.currentState === ItemState.HINT) { // 正常状态和提示状态可以点击 // 这里只是标记,在touchEnd时处理点击 } } // 触摸移动 private onTouchMove(event: EventTouch) { if (this.isDragging && this.currentState === ItemState.EDIT) { const touchLoc = event.getUILocation(); var deltaX = touchLoc.x - this._touchStartPos.x; var deltaY = touchLoc.y - this._touchStartPos.y; this.node.setPosition(this._nodeStartPos.x + deltaX, this._nodeStartPos.y + deltaY, 0); this.data.position.set(this.node.position); } } // 触摸结束 private onTouchEnd(event: EventTouch) { if (this.isDragging) { this.isDragging = false; } else { // 处理点击 if (this.currentState === ItemState.NORMAL || this.currentState === ItemState.HINT) { this.setState(ItemState.FOUND); this.node.emit("itemFound", this); } } } // 缩放滑动条值改变 private onScaleSliderChanged(slider: Slider) { const newScale = this.MIN_SCALE + slider.progress * (this.MAX_SCALE - this.MIN_SCALE); this.spineNode.setScale(newScale, newScale, 1); this.data.scale = newScale; } // 公共接口:设置数据 public setData(data: ItemData) { this.data = { ...data }; this.initializeFromData(); } // 公共接口:获取数据 public getData(): ItemData { return { ...this.data }; } // 公共接口:获取当前状态 public getState(): ItemState { return this.currentState; } // 公共接口:切换到编辑模式 public enterEditMode() { this.setState(ItemState.EDIT); } // 公共接口:退出编辑模式 public exitEditMode() { this.setState(ItemState.NORMAL); } // 公共接口:显示提示 public showHint() { this.setState(ItemState.HINT); } addSpineContentByPrefab(prefab: Prefab) { const spineNode = instantiate(prefab); this.spineNode.addChild(spineNode); } }