const { ccclass, requireComponent, menu, property } = cc._decorator; @ccclass @menu("Plug-in/Button/HoldButton") @requireComponent(cc.Button) export default class HoldButton extends cc.Component { //#region public @property() public MaxTime: number = 2; /** 是否HoldLine */ @property({ displayName: "是否有HoldLine", tooltip: "是否HoldLine" }) public IsHaveHoldLine: boolean = false; @property({ type: cc.Node, visible(): boolean { return this.IsHaveHoldLine; } }) public HoldLine: cc.Node = null; @property({ type: cc.Sprite, visible(): boolean { return this.IsHaveHoldLine; } }) public ProgressBG: cc.Sprite = null; @property({ type: cc.Sprite, visible(): boolean { return this.IsHaveHoldLine; } }) public ProgressLine: cc.Sprite = null; @property({ type: [cc.Component.EventHandler] }) public OnInvoke: cc.Component.EventHandler[] = []; //#endregion //#region private private _isOnInvoke: boolean = false; private _m_isMouseDown: boolean = false; private _m_pressDeltaTime: number = 0; //#endregion //#region Lifecycle protected start(): void { if (this.HoldLine != null) { this.HoldLine.active = false; } } protected update(dt: number): void { if (this._m_isMouseDown) { this._checkHoldAutoStart(dt); } else { if (this.IsHaveHoldLine) { this.HoldLine.active = false; } } } protected onEnable(): void { this.node.on(cc.Node.EventType.TOUCH_START, this._onTouchStart, this); this.node.on(cc.Node.EventType.TOUCH_END, this._onTouchEnd, this); this.node.on(cc.Node.EventType.TOUCH_CANCEL, this._onTouchCancel, this); } protected onDisable(): void { this.node.off(cc.Node.EventType.TOUCH_START, this._onTouchStart, this); this.node.off(cc.Node.EventType.TOUCH_END, this._onTouchEnd, this); this.node.off(cc.Node.EventType.TOUCH_CANCEL, this._onTouchCancel, this); } //#endregion //#region Custom private _checkHoldAutoStart(deltaTime: number): void { this._m_pressDeltaTime += deltaTime; if (this.IsHaveHoldLine) { // 蓄能條顯示特效 this.ProgressLine.fillRange = this._m_pressDeltaTime; } if (this._m_pressDeltaTime > this.MaxTime) { this.node.pauseSystemEvents(true); this._isOnInvoke = true; this._m_isMouseDown = false; if (this.IsHaveHoldLine) { this.HoldLine.active = false; } this._m_pressDeltaTime = 0; if (this.OnInvoke != null) { this.OnInvoke.forEach((eventHandler: cc.Component.EventHandler) => { if (eventHandler) { if (eventHandler.target === "Callback" && eventHandler.component === "Callback" && eventHandler.handler) { (eventHandler.handler)(); } else { eventHandler.emit([this.node.getComponent(cc.Button)]); } } }); } } } //#endregion //#region EventT private _onTouchStart(event: cc.Event.EventTouch): void { if (this._m_isMouseDown) { return; } this._m_isMouseDown = true; if (this.IsHaveHoldLine) { this.HoldLine.active = true; } } private _onTouchEnd(event: cc.Event.EventTouch): void { this.node.resumeSystemEvents(true); this._m_isMouseDown = false; this._m_pressDeltaTime = 0; if (this.IsHaveHoldLine) { this.HoldLine.active = false; } this._isOnInvoke = false; this._checkHoldAutoStart(0); } private _onTouchCancel(event: cc.Event.EventTouch): void { this.node.resumeSystemEvents(true); this._m_isMouseDown = false; this._m_pressDeltaTime = 0; if (this.IsHaveHoldLine) { this.HoldLine.active = false; } this._isOnInvoke = false; this._checkHoldAutoStart(0); } //#endregion }