|
|
@@ -45,7 +45,12 @@ export class GameStartMove extends Component {
|
|
|
@property({ type: Node, tooltip: 'Canvas/GameLevelUI/Gray节点' })
|
|
|
public grayNode: Node = null;
|
|
|
|
|
|
-
|
|
|
+ /** 目标线节点,diban下滑结束后相机将移动到此线的位置 */
|
|
|
+ @property({
|
|
|
+ type: Node,
|
|
|
+ tooltip: 'Target line node. Camera will move to show this line at the bottom after diban slide down animation.'
|
|
|
+ })
|
|
|
+ public targetLineNode: Node = null;
|
|
|
|
|
|
private _originalDibanPos: Vec3 = new Vec3();
|
|
|
|
|
|
@@ -108,6 +113,46 @@ export class GameStartMove extends Component {
|
|
|
.start();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Smoothly move the camera down to show the reference line at bottom.
|
|
|
+ * Requires referenceLineNode to be set.
|
|
|
+ * @param duration 动画时长,默认使用moveDuration
|
|
|
+ */
|
|
|
+ public moveDownSmooth(duration?: number) {
|
|
|
+ if (!this.cameraNode) return;
|
|
|
+
|
|
|
+ const startPos = this.cameraNode.position.clone();
|
|
|
+
|
|
|
+ // Calculate movement based on reference line position
|
|
|
+ const moveDistance = this.calculateMoveDistanceToShowLine();
|
|
|
+ if (moveDistance <= 0) return;
|
|
|
+
|
|
|
+ const targetPos = new Vec3(startPos.x, startPos.y - moveDistance, startPos.z);
|
|
|
+
|
|
|
+ console.log('GameStartMove.moveDownSmooth 镜头平滑下移,开始执行:', {
|
|
|
+ startPos: startPos,
|
|
|
+ targetPos: targetPos,
|
|
|
+ moveDistance: moveDistance
|
|
|
+ });
|
|
|
+
|
|
|
+ // Stop any running tweens on this node to avoid conflicting animations.
|
|
|
+ Tween.stopAllByTarget(this.cameraNode);
|
|
|
+
|
|
|
+ // 使用传入的duration或默认的moveDuration
|
|
|
+ const animationDuration = duration !== undefined ? duration : this.moveDuration;
|
|
|
+
|
|
|
+ tween(this.cameraNode)
|
|
|
+ .to(animationDuration, { position: targetPos }, { easing: 'quadOut' })
|
|
|
+ .call(() => {
|
|
|
+ console.log('GameStartMove.moveDownSmooth 镜头平滑下移完成');
|
|
|
+ // 镜头下移完成时显示Gray遮罩
|
|
|
+ if (this.grayNode) {
|
|
|
+ this.grayNode.active = true;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .start();
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
@@ -156,6 +201,85 @@ export class GameStartMove extends Component {
|
|
|
return Math.max(0, moveDistance); // Ensure we don't move in wrong direction
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Calculate the distance camera needs to move to show the target line at the bottom of the view.
|
|
|
+ * @returns The movement distance in world units
|
|
|
+ */
|
|
|
+ private calculateMoveDistanceToShowTargetLine(): number {
|
|
|
+ if (!this.targetLineNode || !this.cameraNode) {
|
|
|
+ console.warn('GameStartMove.calculateMoveDistanceToShowTargetLine: targetLineNode or cameraNode not set');
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the camera component
|
|
|
+ const cameraComponent = this.cameraNode.getComponent(Camera);
|
|
|
+ if (!cameraComponent) {
|
|
|
+ console.warn('GameStartMove.calculateMoveDistanceToShowTargetLine: Camera component not found');
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the target line's world position
|
|
|
+ const targetLineWorldPos = this.targetLineNode.getWorldPosition();
|
|
|
+
|
|
|
+ // Get camera's current world position
|
|
|
+ const cameraWorldPos = this.cameraNode.getWorldPosition();
|
|
|
+
|
|
|
+ // Calculate camera's view height in world units
|
|
|
+ // For orthographic camera, orthoHeight represents half of the view height
|
|
|
+ const cameraViewHalfHeight = cameraComponent.orthoHeight;
|
|
|
+
|
|
|
+ // Calculate the distance to move camera so that the target line appears at the bottom
|
|
|
+ // We want: cameraWorldPos.y - cameraViewHalfHeight = targetLineWorldPos.y
|
|
|
+ // So: moveDistance = cameraWorldPos.y - targetLineWorldPos.y - cameraViewHalfHeight
|
|
|
+ const moveDistance = cameraWorldPos.y - targetLineWorldPos.y - cameraViewHalfHeight;
|
|
|
+
|
|
|
+ console.log('GameStartMove.calculateMoveDistanceToShowTargetLine 计算移动距离:', {
|
|
|
+ targetLineWorldPos: targetLineWorldPos,
|
|
|
+ cameraWorldPos: cameraWorldPos,
|
|
|
+ cameraViewHalfHeight: cameraViewHalfHeight,
|
|
|
+ moveDistance: moveDistance
|
|
|
+ });
|
|
|
+
|
|
|
+ return moveDistance; // Allow both positive and negative movement
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 平滑移动相机到目标线位置
|
|
|
+ * @param duration 动画时长,默认 0.3s
|
|
|
+ */
|
|
|
+ public moveCameraToTargetLineSmooth(duration: number = 0.3) {
|
|
|
+ if (!this.cameraNode || !this.targetLineNode) {
|
|
|
+ console.warn('GameStartMove.moveCameraToTargetLineSmooth: cameraNode or targetLineNode not set');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const moveDistance = this.calculateMoveDistanceToShowTargetLine();
|
|
|
+ if (moveDistance === 0) {
|
|
|
+ console.log('GameStartMove.moveCameraToTargetLineSmooth: 无需移动相机');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const startPos = this.cameraNode.position.clone();
|
|
|
+ const targetPos = new Vec3(startPos.x, startPos.y - moveDistance, startPos.z);
|
|
|
+
|
|
|
+ console.log('GameStartMove.moveCameraToTargetLineSmooth 相机移动到目标线:', {
|
|
|
+ startPos: startPos,
|
|
|
+ targetPos: targetPos,
|
|
|
+ moveDistance: moveDistance
|
|
|
+ });
|
|
|
+
|
|
|
+ // 停止任何正在运行的相机动画
|
|
|
+ Tween.stopAllByTarget(this.cameraNode);
|
|
|
+
|
|
|
+ // 执行平滑移动动画
|
|
|
+ tween(this.cameraNode)
|
|
|
+ .to(duration, { position: targetPos }, { easing: 'quadOut' })
|
|
|
+ .call(() => {
|
|
|
+ console.log('GameStartMove.moveCameraToTargetLineSmooth 相机移动到目标线完成');
|
|
|
+ })
|
|
|
+ .start();
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 获取参考线在diban父节点坐标系中的位置和diban高度
|
|
|
* @returns 包含referenceLineLocalPos和dibanHeight的对象,如果节点未设置则返回null
|
|
|
@@ -218,8 +342,8 @@ export class GameStartMove extends Component {
|
|
|
})
|
|
|
.start();
|
|
|
|
|
|
- // 同时执行camera下移动画
|
|
|
- this.moveDownInstant();
|
|
|
+ // 同时执行camera平滑下移动画
|
|
|
+ this.moveDownSmooth(duration);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -273,8 +397,8 @@ export class GameStartMove extends Component {
|
|
|
})
|
|
|
.start();
|
|
|
|
|
|
- // 同时执行camera上移动画
|
|
|
- this.moveUpSmooth();
|
|
|
+ // 在diban下滑动画开始的同时,相机平滑移动到目标线位置
|
|
|
+ this.moveCameraToTargetLineSmooth(0.3);
|
|
|
|
|
|
console.log('GameStartMove.slideDibanDownAndHide diban下滑动画已启动');
|
|
|
}
|