| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- import { _decorator, Component, Node, Vec3, tween, Tween } from 'cc';
- const { ccclass, property } = _decorator;
- /**
- * GameStartMove
- *
- * This component is expected to be attached to the main camera node.
- * It provides two public helper methods that other scripts can call:
- * 1. moveDownInstant() – instantly move the camera down by a fixed offset
- * 2. moveUpSmooth() – move the camera back up with a smooth tween animation
- */
- @ccclass('GameStartMove')
- export class GameStartMove extends Component {
- /** The camera node to move. Defaults to the node the script is attached to. */
- @property({
- type: Node,
- tooltip: 'Camera node to move. Leave empty to use the current node.'
- })
- public cameraNode: Node = null;
- /** Offset (in pixels/units) for one step of movement. */
- @property({ tooltip: 'Vertical offset for the camera movement.' })
- public offset: number = 182;
- /** Tween duration for the smooth move-up animation. */
- @property({ tooltip: 'Duration for the smooth move-up tween (seconds).' })
- public moveDuration: number = 0.4;
- private _originalPos: Vec3 = new Vec3();
- private _originalDibanPos: Vec3 = new Vec3();
- onLoad () {
- // Use self node if cameraNode not assigned via the editor.
- if (!this.cameraNode) {
- this.cameraNode = this.node;
- }
- // Save initial position so we can always restore relative to it.
- this._originalPos.set(this.cameraNode.position);
-
- // Save diban original position if available
- if (this.dibanNode) {
- this._originalDibanPos.set(this.dibanNode.position);
- }
- }
- /**
- * Instantly move the camera down by `offset` units.
- */
- public moveDownInstant () {
- if (!this.cameraNode) return;
- const pos = this.cameraNode.position.clone();
- pos.y -= this.offset;
- this.cameraNode.setPosition(pos);
- }
- /**
- * Smoothly move the camera back up by `offset` units using a tween.
- */
- public moveUpSmooth () {
- if (!this.cameraNode) return;
- const startPos = this.cameraNode.position.clone();
- const targetPos = new Vec3(startPos.x, startPos.y + this.offset, startPos.z);
- // Stop any running tweens on this node to avoid conflicting animations.
- Tween.stopAllByTarget(this.cameraNode);
- tween(this.cameraNode)
- .to(this.moveDuration, { position: targetPos }, { easing: 'quadOut' })
- .start();
- }
- /* ========= BlockSelectionUI 动画 ========= */
- /** BlockSelectionUI 根节点(外部在编辑器拖拽赋值) */
- @property({ type: Node, tooltip: 'BlockSelectionUI 根节点' })
- public blockSelectionUI: Node = null;
- /** BlockSelectionUI 中需要下滑的 diban 节点(外部拖拽赋值) */
- @property({ type: Node, tooltip: 'BlockSelectionUI 中的 diban 节点' })
- public dibanNode: Node = null;
- /**
- * 下滑 diban 并在动画结束后隐藏 BlockSelectionUI。
- * @param distance 向下移动距离,默认 300
- * @param duration 动画时长,默认 0.3s
- */
- public slideDibanDownAndHide(distance: number = 300, duration: number = 0.3) {
- console.log('GameStartMove.slideDibanDownAndHide 开始执行');
-
- if (!this.dibanNode || !this.blockSelectionUI) {
- console.log('GameStartMove.slideDibanDownAndHide 条件检查失败:', {
- dibanNode: !!this.dibanNode,
- blockSelectionUI: !!this.blockSelectionUI
- });
- return;
- }
- // 使用存储的原始位置,如果没有存储则使用当前位置
- let originalPos: Vec3;
- if (this._originalDibanPos.equals(Vec3.ZERO)) {
- // 如果没有存储原始位置,使用当前位置并存储它
- originalPos = this.dibanNode.position.clone();
- this._originalDibanPos = originalPos.clone();
- console.log('GameStartMove.slideDibanDownAndHide 首次使用,存储原始位置:', this._originalDibanPos);
- } else {
- // 使用存储的原始位置
- originalPos = this._originalDibanPos.clone();
- console.log('GameStartMove.slideDibanDownAndHide 使用存储的原始位置:', originalPos);
- }
- // 获取当前位置作为动画起始位置
- const currentPos = this.dibanNode.position.clone();
- console.log('GameStartMove.slideDibanDownAndHide 当前位置:', currentPos);
- // 停止现有 tween
- Tween.stopAllByTarget(this.dibanNode);
- const targetPos = new Vec3(currentPos.x, currentPos.y - distance, currentPos.z);
- console.log('GameStartMove.slideDibanDownAndHide 目标位置:', targetPos);
- tween(this.dibanNode)
- .to(duration, { position: targetPos }, { easing: 'quadIn' })
- .call(() => {
- console.log('GameStartMove.slideDibanDownAndHide 动画完成回调');
- // 先隐藏BlockSelectionUI,然后立即重置diban位置到存储的原始位置
- // 这样用户就看不到位置重置的过程
- this.blockSelectionUI.active = false;
- this.dibanNode.setPosition(originalPos);
- console.log('GameStartMove.slideDibanDownAndHide UI已隐藏,位置已重置到:', originalPos);
- })
- .start();
-
- console.log('GameStartMove.slideDibanDownAndHide 动画已启动');
- }
- /**
- * 从底部上滑显示 diban
- * @param distance 从下方移动的距离,默认 300
- * @param duration 动画时长,默认 0.3s
- */
- public slideUpFromBottom(distance: number = 300, duration: number = 0.3) {
- console.log('GameStartMove.slideUpFromBottom 开始执行');
-
- if (!this.dibanNode || !this.blockSelectionUI) {
- console.log('GameStartMove.slideUpFromBottom 条件检查失败:', {
- dibanNode: !!this.dibanNode,
- blockSelectionUI: !!this.blockSelectionUI
- });
- return;
- }
- // 确保BlockSelectionUI可见
- this.blockSelectionUI.active = true;
- // 使用存储的原始位置作为目标位置
- let targetPos: Vec3;
- if (this._originalDibanPos.equals(Vec3.ZERO)) {
- // 如果没有存储原始位置,使用当前位置并存储它
- targetPos = this.dibanNode.position.clone();
- this._originalDibanPos = targetPos.clone();
- console.log('GameStartMove.slideUpFromBottom 首次使用,存储原始位置:', this._originalDibanPos);
- } else {
- // 使用存储的原始位置
- targetPos = this._originalDibanPos.clone();
- console.log('GameStartMove.slideUpFromBottom 使用存储的原始位置:', targetPos);
- }
-
- // 设置初始位置(在目标位置下方)
- const startPos = new Vec3(targetPos.x, targetPos.y - distance, targetPos.z);
- this.dibanNode.setPosition(startPos);
- console.log('GameStartMove.slideUpFromBottom 起始位置:', startPos);
- // 停止现有 tween
- Tween.stopAllByTarget(this.dibanNode);
- // 播放上滑动画到目标位置
- tween(this.dibanNode)
- .to(duration, { position: targetPos }, { easing: 'quadOut' })
- .call(() => {
- console.log('GameStartMove.slideUpFromBottom 动画完成');
- })
- .start();
-
- console.log('GameStartMove.slideUpFromBottom 动画已启动');
- }
- /**
- * 更新保存的diban原始位置(当diban节点在运行时改变时调用)
- */
- public updateDibanOriginalPosition() {
- if (this.dibanNode) {
- this._originalDibanPos.set(this.dibanNode.position);
- console.log('GameStartMove.updateDibanOriginalPosition 存储原始位置:', this._originalDibanPos);
- } else {
- console.log('GameStartMove.updateDibanOriginalPosition dibanNode为空,无法存储位置');
- }
- }
- }
|