feat: 提交资源

This commit is contained in:
han_han9
2025-10-28 21:55:41 +08:00
parent 591f398085
commit 55c4fcd9ae
2146 changed files with 172747 additions and 456 deletions

290
assets/scripts/DialogBox.ts Normal file
View File

@@ -0,0 +1,290 @@
import { _decorator, Button, Component, director, Label, Node, tween, Vec3 } from "cc";
/**
* DialogBox配置选项接口
*/
export interface IDialogBoxOptions {
/** 标题,默认为"提示" */
title?: string;
/** 内容,默认为空 */
content?: string;
/** 确定回调,可选 */
onConfirm?: () => void;
/** 取消回调,可选 */
onCancel?: () => void;
/** 确定按钮文本,默认为"确定" */
confirmText?: string;
/** 取消按钮文本,默认为"取消" */
cancelText?: string;
/** 是否显示取消按钮默认为true */
showCancel?: boolean;
/** 场景中DialogBox节点名称默认为"DialogBox" */
dialogNodeName?: string;
hideClose?: boolean;
}
const { ccclass, property } = _decorator;
/**
* 基础对话框组件
*/
@ccclass("DialogBox")
export class DialogBox extends Component {
// 静态缓存场景中的DialogBox节点
private static sceneDialogBox: DialogBox | null = null;
private static dialogNode: Node | null = null;
@property(Label)
titleLabel: Label = null!;
@property(Label)
contentLabel: Label = null!;
@property(Button)
confirmBtn: Button = null!;
@property(Label)
confirmBtnLabel: Label = null!;
@property(Button)
cancelBtn: Button = null!;
@property(Label)
cancelBtnLabel: Label = null!;
// 回调函数
private onConfirmCallback: (() => void) | null = null;
private onCancelCallback: (() => void) | null = null;
start() {
// 绑定按钮事件
if (this.confirmBtn) {
this.confirmBtn.node.on(Button.EventType.CLICK, this.onConfirmClick, this);
}
if (this.cancelBtn) {
this.cancelBtn.node.on(Button.EventType.CLICK, this.onCancelClick, this);
}
}
/**
* 设置对话框内容
* @param options 配置选项
*/
public setContent(options: IDialogBoxOptions = {}): void {
const {
title = "提示",
content = "",
onConfirm,
onCancel,
confirmText = "确定",
cancelText = "取消",
showCancel = true,
} = options;
// 设置标题和内容
if (this.titleLabel) {
this.titleLabel.string = title;
}
if (this.contentLabel) {
this.contentLabel.string = content;
}
// 设置按钮文本
if (this.confirmBtnLabel) {
this.confirmBtnLabel.string = confirmText;
}
if (this.cancelBtnLabel) {
this.cancelBtnLabel.string = cancelText;
}
// 控制取消按钮显示状态
if (this.cancelBtn) {
this.cancelBtn.node.active = showCancel;
}
// 保存回调函数
this.onConfirmCallback = onConfirm || null;
this.onCancelCallback = onCancel || null;
}
/**
* 显示对话框(带弹出动画)
*/
public show(): void {
this.node.active = true;
// 初始化缩放和透明度
this.node.setScale(Vec3.ZERO);
// 弹出动画缩放从0到1带回弹效果
tween(this.node)
.to(
0.3,
{ scale: Vec3.ONE },
{
easing: "backOut", // 回弹缓动效果
},
)
.start();
}
/**
* 隐藏对话框(带关闭动画)
*/
public hide(): void {
// 停止所有动画
tween(this.node).stop();
// 关闭动画缩放到0
tween(this.node)
.to(
0.2,
{ scale: Vec3.ZERO },
{
easing: "backIn", // 回缩缓动效果
},
)
.call(() => {
// 动画结束后隐藏节点
this.node.active = false;
// 恢复缩放值,为下次显示做准备
this.node.setScale(Vec3.ONE);
})
.start();
// 清理回调
this.onConfirmCallback = null;
this.onCancelCallback = null;
}
/**
* 确定按钮点击事件
*/
private onConfirmClick(): void {
// 执行回调
if (this.onConfirmCallback) {
this.onConfirmCallback();
}
// 隐藏对话框
this.hide();
}
/**
* 取消按钮点击事件
*/
private onCancelClick(): void {
// 执行回调
if (this.onCancelCallback) {
this.onCancelCallback();
}
// 隐藏对话框
this.hide();
}
onDestroy() {
// 清理事件监听
if (this.confirmBtn) {
this.confirmBtn.node.off(Button.EventType.CLICK, this.onConfirmClick, this);
}
if (this.cancelBtn) {
this.cancelBtn.node.off(Button.EventType.CLICK, this.onCancelClick, this);
}
// 停止所有动画
tween(this.node).stop();
// 清理静态引用
if (DialogBox.sceneDialogBox === this) {
DialogBox.sceneDialogBox = null;
DialogBox.dialogNode = null;
}
}
/**
* 静态方法:显示对话框
* @param options 配置选项
*/
public static showDialog(options: IDialogBoxOptions = {}): void {
const { dialogNodeName = "DialogBox" } = options;
// 获取场景中的DialogBox节点
if (!DialogBox.sceneDialogBox || !DialogBox.dialogNode?.isValid) {
DialogBox.findDialogBoxInScene(dialogNodeName);
}
if (!DialogBox.sceneDialogBox) {
return; // 场景中未找到DialogBox节点
}
// 设置内容并显示
DialogBox.sceneDialogBox.setContent(options);
DialogBox.sceneDialogBox.show();
}
/**
* 静态方法:隐藏当前对话框(带动画)
*/
public static hideCurrentDialog(): void {
if (DialogBox.sceneDialogBox) {
DialogBox.sceneDialogBox.hide();
}
}
/**
* 静态方法:立即隐藏当前对话框(无动画)
*/
public static hideCurrentDialogImmediately(): void {
if (DialogBox.sceneDialogBox) {
// 停止所有动画
tween(DialogBox.sceneDialogBox.node).stop();
// 立即隐藏
DialogBox.sceneDialogBox.node.active = false;
DialogBox.sceneDialogBox.node.setScale(Vec3.ONE);
// 清理回调
DialogBox.sceneDialogBox.onConfirmCallback = null;
DialogBox.sceneDialogBox.onCancelCallback = null;
}
}
/**
* 在场景中查找DialogBox节点
* @param nodeName 节点名称
*/
private static findDialogBoxInScene(nodeName: string): void {
const scene = director.getScene();
if (!scene) {
return;
}
// 递归查找DialogBox节点
const findNodeRecursively = (node: Node, targetName: string): Node | null => {
if (node.name === targetName) {
return node;
}
for (const child of node.children) {
const found = findNodeRecursively(child, targetName);
if (found) {
return found;
}
}
return null;
};
const dialogNode = findNodeRecursively(scene, nodeName);
if (dialogNode) {
const dialogComponent = dialogNode.getComponent(DialogBox);
if (dialogComponent) {
DialogBox.sceneDialogBox = dialogComponent;
DialogBox.dialogNode = dialogNode;
// 初始状态为隐藏
dialogNode.active = false;
}
}
}
}