- StoryManager: 剧情管理器 - DialogueBox: 对话框组件(带打字机效果) - CharacterView: 立绘组件 - ChoiceButton: 选项按钮 - AffectionSystem: 好感度系统 - chapter1.json: 示例剧情
137 lines
3.0 KiB
TypeScript
137 lines
3.0 KiB
TypeScript
import { _decorator, Component, Node, Label, Button, Sprite, tween, Vec3, Color } from 'cc';
|
|
|
|
const { ccclass, property } = _decorator;
|
|
|
|
@ccclass('ChoiceButton')
|
|
export class ChoiceButton extends Component {
|
|
@property(Label)
|
|
textLabel: Label;
|
|
|
|
@property(Button)
|
|
button: Button;
|
|
|
|
@property(Sprite)
|
|
background: Sprite;
|
|
|
|
private onClickCallback: () => void = null;
|
|
private isClicked: boolean = false;
|
|
|
|
onLoad() {
|
|
// 确保有 Button 组件
|
|
if (!this.button) {
|
|
this.button = this.getComponent(Button);
|
|
}
|
|
|
|
if (this.button) {
|
|
this.button.node.on('click', this.onButtonClick, this);
|
|
}
|
|
|
|
// 默认隐藏
|
|
this.node.active = false;
|
|
}
|
|
|
|
onDestroy() {
|
|
if (this.button) {
|
|
this.button.node.off('click', this.onButtonClick, this);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 设置选项文本和回调
|
|
*/
|
|
setup(text: string, onClick: () => void) {
|
|
if (this.textLabel) {
|
|
this.textLabel.string = text;
|
|
}
|
|
|
|
this.onClickCallback = onClick;
|
|
this.isClicked = false;
|
|
this.node.active = true;
|
|
|
|
// 重置状态
|
|
this.setHoverState(false);
|
|
}
|
|
|
|
/**
|
|
* 按钮点击处理
|
|
*/
|
|
private onButtonClick() {
|
|
if (this.isClicked) return;
|
|
|
|
this.isClicked = true;
|
|
|
|
// 播放点击动画
|
|
this.playClickAnimation(() => {
|
|
// 执行回调
|
|
if (this.onClickCallback) {
|
|
this.onClickCallback();
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 播放点击动画
|
|
*/
|
|
private playClickAnimation(callback: () => void) {
|
|
// 缩小动画
|
|
tween(this.node)
|
|
.to(0.1, { scale: new Vec3(0.95, 0.95, 1) })
|
|
.to(0.1, { scale: new Vec3(1, 1, 1) })
|
|
.call(callback)
|
|
.start();
|
|
}
|
|
|
|
/**
|
|
* 设置悬停状态
|
|
*/
|
|
setHoverState(isHover: boolean) {
|
|
if (!this.background) return;
|
|
|
|
// 简单的悬停效果
|
|
// 实际项目中可以根据需要调整颜色或缩放
|
|
const targetScale = isHover ? 1.05 : 1;
|
|
|
|
tween(this.node)
|
|
.to(0.1, { scale: new Vec3(targetScale, targetScale, 1) })
|
|
.start();
|
|
}
|
|
|
|
/**
|
|
* 设置按钮可用状态
|
|
*/
|
|
setEnabled(enabled: boolean) {
|
|
if (this.button) {
|
|
this.button.interactable = enabled;
|
|
}
|
|
|
|
// 禁用时降低透明度
|
|
const opacity = enabled ? 255 : 128;
|
|
if (this.background) {
|
|
this.background.color = new Color(255, 255, 255, opacity);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取选项文本
|
|
*/
|
|
getText(): string {
|
|
return this.textLabel ? this.textLabel.string : '';
|
|
}
|
|
|
|
/**
|
|
* 隐藏选项
|
|
*/
|
|
hide() {
|
|
this.node.active = false;
|
|
this.isClicked = false;
|
|
}
|
|
|
|
/**
|
|
* 显示选项
|
|
*/
|
|
show() {
|
|
this.node.active = true;
|
|
this.isClicked = false;
|
|
}
|
|
}
|