|
|
@@ -0,0 +1,94 @@
|
|
|
+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();
|
|
|
+
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 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) {
|
|
|
+ if (!this.dibanNode || !this.blockSelectionUI) return;
|
|
|
+
|
|
|
+ const originalPos = this.dibanNode.position.clone();
|
|
|
+
|
|
|
+ // 停止现有 tween
|
|
|
+ Tween.stopAllByTarget(this.dibanNode);
|
|
|
+
|
|
|
+ tween(this.dibanNode)
|
|
|
+ .to(duration, { position: new Vec3(originalPos.x, originalPos.y - distance, originalPos.z) }, { easing: 'quadIn' })
|
|
|
+ .call(() => {
|
|
|
+ this.blockSelectionUI.active = false;
|
|
|
+ this.dibanNode.setPosition(originalPos);
|
|
|
+ })
|
|
|
+ .start();
|
|
|
+ }
|
|
|
+}
|