优化按钮组件

This commit is contained in:
dgflash
2024-06-04 17:29:42 +08:00
parent 0ac4351e12
commit 9590227756
3 changed files with 26 additions and 122 deletions

View File

@@ -8,7 +8,7 @@ const { ccclass, property, menu } = _decorator;
@menu('ui/button/ButtonSimple')
export default class ButtonSimple extends Component {
@property({
tooltip: "是否只触发一次"
tooltip: "是否只触发一次"
})
private once: boolean = false;

View File

@@ -1,79 +1,23 @@
import { AudioClip, Component, Enum, EventHandler, EventTouch, Node, _decorator, game } from "cc";
import { AudioClip, Button, EventTouch, _decorator, game } from "cc";
import { oops } from "../../../core/Oops";
const { ccclass, property, menu } = _decorator;
enum ButtonType {
/** 短按 */
ClickShort,
/** 长按 */
ClickLong
}
/**
* 通用按钮
* 1、防连点
* 2、短按触发
* 3、长按触发
* 4、按钮点击触发音效
* 5、防连点
* 2、按钮点击触发音效
*/
Enum(ButtonType);
@ccclass("UIButton")
@menu('ui/button/UIButton')
export default class UIButton extends Component {
@property
_type: ButtonType = ButtonType.ClickShort;
@property({
tooltip: "按钮类型",
type: ButtonType
})
get type() {
return this._type;
}
set type(val) {
this._type = val;
}
//#region 长按相关属性
@property({
tooltip: "长按时间(秒)",
visible: function (this) {
//@ts-ignore
return this._type == ButtonType.ClickLong;
}
})
time: number = 1;
@property({
type: [EventHandler],
tooltip: "长按触发事件",
visible: function (this) {
//@ts-ignore
return this._type == ButtonType.ClickLong;
}
})
clickEvents: EventHandler[] = [];
protected _passTime = 0;
protected _isTouchLong: boolean = true;
protected _event: EventTouch | null = null;
//#endregion
//#region 短按相关属性
export default class UIButton extends Button {
@property({
tooltip: "每次触发间隔"
})
private interval: number = 500;
/** 触摸次数 */
private _touchCount = 0;
/** 触摸结束时间 */
private _touchEndTime = 0;
//#endregion
@property({
tooltip: "是否只触发一次"
tooltip: "是否只触发一次"
})
private once: boolean = false;
@@ -83,24 +27,13 @@ export default class UIButton extends Component {
})
private effect: AudioClip = null!;
onLoad() {
this.node.on(Node.EventType.TOUCH_START, this.onTouchtStart, this);
this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
}
/** 触摸开始 */
private onTouchtStart(event: EventTouch) {
if (this._type == ButtonType.ClickLong) {
this._event = event;
this._passTime = 0;
this._isTouchLong = false;
this.enabled = true;
}
}
/** 触摸次数 */
private _touchCount = 0;
/** 触摸结束时间 */
private _touchEndTime = 0;
/** 触摸结束 */
private onTouchEnd(event: EventTouch) {
protected _onTouchEnded(event: EventTouch) {
// 是否只触发一次
if (this.once) {
if (this._touchCount > 0) {
@@ -110,54 +43,20 @@ export default class UIButton extends Component {
this._touchCount++;
}
if (this._type == ButtonType.ClickShort) {
// 防连点500毫秒出发一次事件
if (this._touchEndTime && game.totalTime - this._touchEndTime < this.interval) {
event.propagationStopped = true;
}
else {
this._touchEndTime = game.totalTime;
}
// 短按触摸音效
if (this.effect) oops.audio.playEffect(this.effect);
// 防连点500毫秒出发一次事件
if (this._touchEndTime && game.totalTime - this._touchEndTime < this.interval) {
event.propagationStopped = true;
}
else if (this._type == ButtonType.ClickLong) {
if (this._passTime > this.time) {
event.propagationStopped = true;
}
this._event = null;
this._passTime = 0;
this._isTouchLong = false;
else {
this._touchEndTime = game.totalTime;
super._onTouchEnded(event);
}
}
/** 引擎更新事件 */
update(dt: number) {
if (this._event && !this._isTouchLong) {
this._passTime += dt;
if (this._passTime >= this.time) {
this._isTouchLong = true;
this.clickEvents.forEach(event => {
event.emit([event.customEventData]);
});
this._event = null;
this._isTouchLong = false;
this.enabled = false;
// 长按音效
if (this._type == ButtonType.ClickLong && this.effect) oops.audio.playEffect(this.effect);
}
}
// 短按触摸音效
if (this.effect) oops.audio.playEffect(this.effect);
}
onDestroy() {
this.node.off(Node.EventType.TOUCH_START, this.onTouchtStart, this);
this.node.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
this.node.off(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
if (this.effect) oops.audio.releaseEffect(this.effect);
}
}

View File

@@ -4,7 +4,7 @@
* @LastEditors: dgflash
* @LastEditTime: 2022-12-13 11:36:00
*/
import { Asset, Button, Component, EventKeyboard, EventTouch, Input, Node, __private, _decorator, input } from "cc";
import { Asset, Button, Component, EventHandler, EventKeyboard, EventTouch, Input, Node, __private, _decorator, input } from "cc";
import { oops } from "../../core/Oops";
import { EventDispatcher } from "../../core/common/event/EventDispatcher";
import { EventMessage, ListenerFunc } from "../../core/common/event/EventMessage";
@@ -245,14 +245,19 @@ export class GameComponent extends Component {
}
}, this);
// Cocos Creator Button组件批量绑定触摸事件
// Cocos Creator Button组件批量绑定触摸事件使用UIButton支持放连点功能
const regex = /<([^>]+)>/;
var buttons = this.node.getComponentsInChildren<Button>(Button);
buttons.forEach((b: Button) => {
var node = b.node;
var self: any = this;
var func = self[node.name];
if (func) {
node.on(Node.EventType.TOUCH_END, func, this);
var event = new EventHandler();
event.target = this.node;
event.handler = b.node.name;
event.component = this.name.match(regex)![1];
b.clickEvents.push(event);
}
else
console.error(`名为【${node.name}】的按钮事件方法不存在`);