| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- 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 high-level animation methods for block selection mode transitions:
- * 1. enterBlockSelectionMode() – complete animation for entering block selection (camera down + UI slide up)
- * 2. exitBlockSelectionMode() – complete animation for exiting block selection (camera up + UI slide down)
- *
- * Also provides low-level methods for specific use cases:
- * - moveDownInstant() – instantly move the camera down by a fixed offset
- * - moveUpSmooth() – move the camera back up with a smooth tween animation
- * - slideUpFromBottom() – slide UI up from bottom
- * - slideDibanDownAndHide() – slide UI down and hide
- */
- @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();
- /** 需要下滑的 diban 节点(外部拖拽赋值) */
- @property({ type: Node, tooltip: 'diban 节点' })
- public dibanNode: Node = null;
- /** Gray遮罩节点 */
- @property({ type: Node, tooltip: 'Canvas/GameLevelUI/Gray节点' })
- public grayNode: Node = null;
- 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 dibanNode is assigned
- 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);
- console.log('GameStartMove.moveDownInstant 镜头下移,当前位置:', pos);
- // 镜头下移时显示Gray遮罩
- if (this.grayNode) {
- this.grayNode.active = true;
- }
- }
- /**
- * 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.
- console.log('GameStartMove.moveUpSmooth 镜头上移,开始执行');
- Tween.stopAllByTarget(this.cameraNode);
- tween(this.cameraNode)
- .to(this.moveDuration, { position: targetPos }, { easing: 'quadOut' })
- .start();
- }
- /* ========= 高级动画方法 ========= */
- /**
- * 上滑 diban节点,进入备战状态。同时镜头下移。
- * @param distance 向上移动距离,默认 300
- * @param duration 动画时长,默认 0.3s
- */
- public slideUpFromBottom(distance: number = 300, duration: number = 0.3) {
- console.log('GameStartMove.slideUpFromBottom 开始执行');
-
- // 使用装饰器属性中的diban节点
- if (!this.dibanNode) {
- console.warn('GameStartMove.slideUpFromBottom diban节点未设置');
- return;
- }
-
- // 保存diban的原始位置(如果还没保存的话)
- if (this._originalDibanPos.equals(Vec3.ZERO)) {
- this._originalDibanPos.set(this.dibanNode.position);
- }
-
- // 设置diban初始位置(在屏幕下方)
- const startPos = this._originalDibanPos.clone();
- startPos.y -= distance;
- this.dibanNode.setPosition(startPos);
-
- console.log('GameStartMove.slideUpFromBottom diban初始位置:', startPos);
- console.log('GameStartMove.slideUpFromBottom diban目标位置:', this._originalDibanPos);
-
- // 停止任何正在运行的动画
- Tween.stopAllByTarget(this.dibanNode);
-
- // 执行上滑动画
- tween(this.dibanNode)
- .to(duration, { position: this._originalDibanPos }, { easing: 'quadOut' })
- .call(() => {
- console.log('GameStartMove.slideUpFromBottom diban上滑动画完成');
- })
- .start();
-
- // 同时执行camera下移动画
- this.moveDownInstant();
-
- console.log('GameStartMove.slideUpFromBottom diban上滑动画已启动');
- }
- /**
- * 下滑 diban节点,结束备战进入playing 状态。
- * @param distance 向下移动距离,默认 300
- * @param duration 动画时长,默认 0.3s
- */
- public slideDibanDownAndHide(distance: number = 300, duration: number = 0.3) {
- console.log('GameStartMove.slideDibanDownAndHide 开始执行');
-
- // 使用装饰器属性中的diban节点
- if (!this.dibanNode) {
- console.warn('GameStartMove.slideDibanDownAndHide diban节点未设置');
- return;
- }
-
- // 获取当前位置
- const currentPos = this.dibanNode.position.clone();
- console.log('GameStartMove.slideDibanDownAndHide diban当前位置:', currentPos);
-
- // 计算目标位置(向下移动)
- const targetPos = new Vec3(currentPos.x, currentPos.y - distance, currentPos.z);
- console.log('GameStartMove.slideDibanDownAndHide diban目标位置:', targetPos);
-
- // 停止任何正在运行的动画
- Tween.stopAllByTarget(this.dibanNode);
-
- // 执行下滑动画
- tween(this.dibanNode)
- .to(duration, { position: targetPos }, { easing: 'quadOut' })
- .call(() => {
- console.log('GameStartMove.slideDibanDownAndHide diban下滑动画完成');
- // 动画完成时隐藏Gray遮罩
- if (this.grayNode) {
- this.grayNode.active = false;
- }
- })
- .start();
-
- // 同时执行camera上移动画
- this.moveUpSmooth();
-
- console.log('GameStartMove.slideDibanDownAndHide diban下滑动画已启动');
- }
- }
|