123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- import { _decorator, Component, Node, Button, Vec3, tween, Tween, resources, sp } from 'cc';
- import { DialogueManager } from './DialogueManager';
- const { ccclass, property } = _decorator;
- @ccclass('CharacterManager')
- export class CharacterManager extends Component {
- @property({
- type: DialogueManager,
- tooltip: '对话框管理器'
- })
- dialogueManager: DialogueManager = null;
- @property({
- type: Node,
- tooltip: '人物节点'
- })
- characterNode: Node = null;
- @property({
- type: Button,
- tooltip: '放行按钮(向右移动)'
- })
- letPassButton: Button = null;
- @property({
- type: Button,
- tooltip: '赶走按钮(向左移动)'
- })
- dismissButton: Button = null;
- @property({
- tooltip: '人物移动动画持续时间(秒)'
- })
- moveDuration: number = 1.0;
- @property({
- tooltip: '人物移动距离(像素)'
- })
- moveDistance: number = 300;
-
- private initialPosition: Vec3 = null;
- private currentAnimation: Tween<Node> = null;
- start() {
- // 记录人物初始位置
- if (this.characterNode) {
- this.initialPosition = this.characterNode.position.clone();
- this.initialPosition.x += 400; // 初始位置的x坐标增加400
- }
- // 不再直接绑定按钮事件,这会导致回调函数丢失
- // 这些按钮事件在GameFlowManager中处理
- }
-
- /**
- * 设置角色外观
- * @param characterId 角色ID
- * @param skinName 皮肤名称
- * @param onComplete 外观设置完成后的回调函数
- */
- public setupCharacterAppearance(characterId: number, skinName: string, onComplete?: () => void): void {
- if (!this.characterNode) {
- console.error('人物节点未设置');
- return;
- }
- // 构建角色资源路径(左边补0确保两位数)
- const characterFolderName = characterId < 10 ? `0${characterId}` : `${characterId}`;
- const characterPath = `${characterFolderName}`;
-
- // 加载角色骨骼动画资源
- resources.load(`${characterPath}/${characterId}`, sp.SkeletonData, (err, skeletonData) => {
- if (err) {
- console.error(`加载角色资源失败: ${characterPath}/${characterId}`, err);
- return;
- }
-
- // 获取骨骼动画组件
- const skeletonComponent = this.characterNode.getComponent(sp.Skeleton);
- if (skeletonComponent) {
- // 设置骨骼数据
- skeletonComponent.skeletonData = skeletonData;
- skeletonComponent.setSkin(skinName);
- skeletonComponent.setAnimation(0, 'loop', true);
-
- console.log(`设置角色: ${characterId}, 皮肤: ${skinName}`);
-
- // 确保回调是一个函数再执行
- if (onComplete && typeof onComplete === 'function') {
- try {
- onComplete();
- } catch (error) {
- console.error('执行外观设置回调时出错:', error);
- }
- }
- } else {
- console.error('人物节点上没有sp.Skeleton组件');
- }
- });
- }
- /**
- * 人物移动到右侧(放行)
- * @param onComplete 移动完成后的回调函数
- */
- public moveCharacterRight(onComplete?: () => void): void {
- if (!this.characterNode || !this.initialPosition) {
- return;
- }
- // 隐藏对话框
- if (this.dialogueManager) {
- this.dialogueManager.hideDialogue();
- }
- // 停止当前动画
- if (this.currentAnimation) {
- this.currentAnimation.stop();
- }
- // 目标位置:向右移动
- const targetPos = new Vec3(
- this.initialPosition.x + this.moveDistance,
- this.initialPosition.y,
- this.initialPosition.z
- );
- // 创建动画
- this.currentAnimation = tween(this.characterNode)
- .to(this.moveDuration, { position: targetPos }, { easing: 'cubicOut' })
- .call(() => {
- // 动画完成回调
- this.currentAnimation = null;
-
- // 确保回调是一个函数再执行
- if (onComplete && typeof onComplete === 'function') {
- try {
- onComplete();
- } catch (error) {
- console.error('执行向右移动回调时出错:', error);
- }
- }
- })
- .start();
- }
- /**
- * 人物移动到左侧(赶走)
- * @param onComplete 移动完成后的回调函数
- */
- public moveCharacterLeft(onComplete?: () => void): void {
- if (!this.characterNode || !this.initialPosition) {
- return;
- }
- // 隐藏对话框
- if (this.dialogueManager) {
- this.dialogueManager.hideDialogue();
- }
- // 停止当前动画
- if (this.currentAnimation) {
- this.currentAnimation.stop();
- }
- // 目标位置:向左移动
- const targetPos = new Vec3(
- this.initialPosition.x - this.moveDistance,
- this.initialPosition.y,
- this.initialPosition.z
- );
- // 创建动画
- this.currentAnimation = tween(this.characterNode)
- .to(this.moveDuration, { position: targetPos }, { easing: 'cubicOut' })
- .call(() => {
- // 动画完成回调
- this.currentAnimation = null;
-
- // 确保回调是一个函数再执行
- if (onComplete && typeof onComplete === 'function') {
- try {
- onComplete();
- } catch (error) {
- console.error('执行向左移动回调时出错:', error);
- }
- }
- })
- .start();
- }
- /**
- * 新人物从左向右进入
- * @param onComplete 移动完成后的回调函数
- */
- public characterEnter(onComplete?: () => void): void {
- console.log('characterEnter');
- if (!this.characterNode) return;
- // 隐藏对话框
- if (this.dialogueManager) {
- this.dialogueManager.hideDialogue();
- }
- // 停止当前动画
- if (this.currentAnimation) {
- this.currentAnimation.stop();
- }
- // 设置起始位置(在左侧)
- const startPos = new Vec3(
- this.initialPosition.x - this.moveDistance,
- this.initialPosition.y,
- this.initialPosition.z
- );
- this.characterNode.position = startPos;
- // 创建动画,移动到初始位置
- this.currentAnimation = tween(this.characterNode)
- .to(this.moveDuration, { position: this.initialPosition }, { easing: 'cubicOut' })
- .call(() => {
- // 动画完成回调
- this.currentAnimation = null;
-
- // 确保回调是一个函数再执行
- if (onComplete && typeof onComplete === 'function') {
- try {
- onComplete();
- } catch (error) {
- console.error('执行角色进入回调时出错:', error);
- }
- }
- })
- .start();
- }
- /**
- * 重置人物位置到初始位置
- */
- public resetCharacterPosition(): void {
- if (this.characterNode && this.initialPosition) {
- // 停止当前动画
- if (this.currentAnimation) {
- this.currentAnimation.stop();
- this.currentAnimation = null;
- }
- // 直接设置到初始位置
- this.characterNode.position = this.initialPosition.clone();
- }
- }
- onDestroy() {
- // 不再需要移除这些事件监听
- }
- }
|