123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- 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);
- }
- }
|