From 76c6fca2a52ff4e47383da740beaf3952c2c5916 Mon Sep 17 00:00:00 2001 From: panw Date: Fri, 6 Jun 2025 10:44:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=20=E6=8A=80=E8=83=BD?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=92=8C=E8=8B=B1=E9=9B=84=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/script/game/BezierMove.meta | 9 + assets/script/game/BezierMove/BezierMove.ts | 571 ++++++++++++++++++ .../script/game/BezierMove/BezierMove.ts.meta | 9 + .../script/game/common/SingletonModuleComp.ts | 46 +- assets/script/game/common/config/Mission.ts | 26 +- assets/script/game/map/MissionComp.ts | 44 +- 6 files changed, 639 insertions(+), 66 deletions(-) create mode 100644 assets/script/game/BezierMove.meta create mode 100644 assets/script/game/BezierMove/BezierMove.ts create mode 100644 assets/script/game/BezierMove/BezierMove.ts.meta diff --git a/assets/script/game/BezierMove.meta b/assets/script/game/BezierMove.meta new file mode 100644 index 00000000..8aa4b2c3 --- /dev/null +++ b/assets/script/game/BezierMove.meta @@ -0,0 +1,9 @@ +{ + "ver": "1.2.0", + "importer": "directory", + "imported": true, + "uuid": "6c227a87-4bae-4eb8-b109-39b5444eb904", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/script/game/BezierMove/BezierMove.ts b/assets/script/game/BezierMove/BezierMove.ts new file mode 100644 index 00000000..1eba142a --- /dev/null +++ b/assets/script/game/BezierMove/BezierMove.ts @@ -0,0 +1,571 @@ +import { _decorator, Component, Node, view, UITransform, Vec3, math, EventHandler, Graphics, Color, TweenEasing, Enum } from 'cc'; +const { ccclass, property } = _decorator; + +// 定义缓动类型枚举 +export enum EasingType { + linear = 'linear', + smooth = 'smooth', + fade = 'fade', + quadIn = 'quadIn', + quadOut = 'quadOut', + quadInOut = 'quadInOut', + quadOutIn = 'quadOutIn', + cubicIn = 'cubicIn', + cubicOut = 'cubicOut', + cubicInOut = 'cubicInOut', + cubicOutIn = 'cubicOutIn', + quartIn = 'quartIn', + quartOut = 'quartOut', + quartInOut = 'quartInOut', + quartOutIn = 'quartOutIn', + quintIn = 'quintIn', + quintOut = 'quintOut', + quintInOut = 'quintInOut', + quintOutIn = 'quintOutIn', + sineIn = 'sineIn', + sineOut = 'sineOut', + sineInOut = 'sineInOut', + sineOutIn = 'sineOutIn', + expoIn = 'expoIn', + expoOut = 'expoOut', + expoInOut = 'expoInOut', + expoOutIn = 'expoOutIn', + circIn = 'circIn', + circOut = 'circOut', + circInOut = 'circInOut', + circOutIn = 'circOutIn', + elasticIn = 'elasticIn', + elasticOut = 'elasticOut', + elasticInOut = 'elasticInOut', + elasticOutIn = 'elasticOutIn', + backIn = 'backIn', + backOut = 'backOut', + backInOut = 'backInOut', + backOutIn = 'backOutIn', + bounceIn = 'bounceIn', + bounceOut = 'bounceOut', + bounceInOut = 'bounceInOut', + bounceOutIn = 'bounceOutIn', +} + +export enum ControlPointSideType { + Left = 1, + Right = -1, + Random = 0, +} + +@ccclass('BezierMove') +export class BezierMove extends Component { + @property({ displayName: '速度' }) + speed: number = 600; // 移动速度,单位:像素/秒 + + @property({ displayName: '控制点方向', tooltip: '0=随机, 1=左侧,-1=右侧(相对于从起点到终点的方向)' }) + controlPointSide: ControlPointSideType = ControlPointSideType.Left; // 控制点位置:0=随机,1=左侧,-1=右侧(相对于从起点到终点的方向) + + @property({ displayName: '控制点偏移系数', tooltip: '0~1之间,控制点偏移系数,值越大曲线越弯曲' }) + controlPointOffset: number = 0.5; // 控制点偏移系数,值越大曲线越弯曲 + + @property({ displayName: '控制点随机性', tooltip: '0~1之间,控制点随机性,值越大随机性越强' }) + controlPointRandomness: number = 0.3; // 控制点随机性,值越大随机性越强 + + @property({ displayName: '自动旋转' }) + autoRotate: boolean = true; // 是否自动旋转以面向移动方向 + + @property({ displayName: '显示轨迹' }) + showTrajectory: boolean = true; // 是否显示移动轨迹 + + @property({ displayName: '轨迹颜色' }) + trajectoryColor: Color = new Color(0, 255, 0, 255); // 轨迹颜色,默认绿色 + + @property({ displayName: '轨迹宽度' }) + trajectoryWidth: number = 3; // 轨迹宽度 + + @property({ displayName: '缓动函数', type: Enum(EasingType) }) + easing: TweenEasing = EasingType.linear; // 缓动效果类型,默认为线性 + + @property({ displayName: '角度平滑系数', tooltip: '0~1之间,值越小旋转越平滑,0表示不旋转,1表示立即旋转' }) + rotationSmoothness: number = 0.6; // 角度平滑系数,值越小旋转越平滑 + + private _graphics: Graphics | null = null; // Graphics组件引用 + private _currentAngle: number = 0; // 当前角度 + + private _startPoint: Vec3 = new Vec3(); + private _endPoint: Vec3 = new Vec3(); + private _controlPoint: Vec3 = new Vec3(); + private _t: number = 0; // Bezier曲线参数 (0 到 1) + private _totalTime: number = 0; // 完成当前曲线所需的时间 + private _isMoving: boolean = false; // 是否正在移动 + private _moveEndCallback: Function = null; // 移动完成回调函数 + private _moveEndTarget: any; // 移动完成回调函数的目标对象 + private _moveStartCallback: Function = null; // 移动开始回调函数, (totalTime: number) => void + private _moveStartTarget: any; // 移动开始回调函数的目标对象 + + onEnable() { + // 初始化起点为当前位置 + this._startPoint.set(this.node.position); + + // 初始化当前角度为节点当前角度 + this._currentAngle = this.node.angle; + + // 初始化Graphics组件用于绘制轨迹 + this._initGraphics(); + + } + + onDisable() { + + // 清理Graphics资源 + if (this._graphics) { + this._graphics.clear(); + // 确保Graphics节点也被销毁 + if (this._graphics.node && this._graphics.node.isValid) { + // 查找并销毁与当前实例关联的唯一轨迹节点 + const uniqueNodeName = `TrajectoryGraphics_${this.node.uuid}`; + this._graphics.node.destroy(); + } + } + } + + onMoveComplete(callback: Function, target: any) { + this._moveEndCallback = callback; + this._moveEndTarget = target; + } + + onMoveStart(callback: Function, target: any) { + this._moveStartCallback = callback; + this._moveStartTarget = target; + } + + + update(deltaTime: number) { + if (!this._isMoving || this._totalTime <= 0) return; // 如果没有移动或路径生成失败,则返回 + + // 更新进度 + this._t += deltaTime / this._totalTime; + + // 应用缓动效果 + let easedT = this._applyEasing(this._t); + + if (this._t >= 1.0) { + // 到达终点 + this.node.setPosition(this._endPoint); + this._isMoving = false; + // 触发移动完成事件 + // EventHandler.emitEvents(this.onMoveComplete, this); + this._moveEndCallback && this._moveEndCallback.apply(this._moveEndTarget); + // 清除轨迹 + if (this.showTrajectory && this._graphics) { + this._graphics.clear(); + // 确保Graphics节点回到原始父节点 + if (this._graphics.node.parent !== this.node) { + const graphicsNode = this._graphics.node; + if (graphicsNode.parent) { + graphicsNode.removeFromParent(); + } + this.node.addChild(graphicsNode); + } + } + } else { + // 计算贝塞尔曲线上的当前位置,使用缓动后的t值 + const currentPos = this._calculateQuadraticBezierPoint(easedT, this._startPoint, this._controlPoint, this._endPoint); + this.node.setPosition(currentPos); + + // 如果启用了自动旋转,计算切线(方向)进行旋转 + if (this.autoRotate) { + const tangent = this._calculateQuadraticBezierTangent(easedT, this._startPoint, this._controlPoint, this._endPoint); + if (tangent.lengthSqr() > 0.001) { // 避免除以零或NaN角度 + // 计算角度(度)。Atan2给出弧度。 + // 加90度是因为角度0指向上方(在Cocos Creator 2D中沿Y轴) + const targetAngle = math.toDegree(Math.atan2(tangent.y, tangent.x)) - 90; + + // 使用平滑插值方法计算新角度 + this._currentAngle = this._smoothAngle(this._currentAngle, targetAngle, this.rotationSmoothness); + this.node.angle = this._currentAngle; + } + } + } + } + + /** + * 移动到指定位置 + * @param targetPos 目标位置 + */ + public moveTo(targetPos: Vec3): void { + // 设置起点为当前位置 + this._startPoint.set(this.node.position); + // 设置终点为目标位置 + this._endPoint.set(targetPos); + + // 记录当前角度,用于平滑过渡 + this._currentAngle = this.node.angle; + + // 自动生成控制点 + this._generateControlPoint(); + + // 估算曲线长度以计算总时间 + const approxLength = Vec3.distance(this._startPoint, this._controlPoint) + Vec3.distance(this._controlPoint, this._endPoint); + this._totalTime = approxLength / this.speed; + if (this._totalTime < 0.1) { // 确保最小持续时间 + this._totalTime = 0.1; + } + + // 如果启用了轨迹显示,绘制轨迹 + if (this.showTrajectory) { + this._drawTrajectory(); + } + + // 重置进度并开始移动 + this._t = 0; + this._isMoving = true; + + this._moveStartCallback && this._moveStartCallback.apply(this._moveStartTarget, [this._totalTime]); + } + + /** + * 自动生成控制点 + */ + private _generateControlPoint(): void { + // 计算起点和终点的中点 + const midPoint = new Vec3(); + Vec3.lerp(midPoint, this._startPoint, this._endPoint, 0.5); + + // 计算从起点到终点的向量 + const direction = new Vec3(); + Vec3.subtract(direction, this._endPoint, this._startPoint); + + // 计算垂直于方向的向量(在2D中,交换x和y并取反其中一个) + const perpendicular = new Vec3(-direction.y, direction.x, 0); + Vec3.normalize(perpendicular, perpendicular); + + // 根据controlPointSide参数决定控制点在哪一侧 + let sideMultiplier = 1; + if (this.controlPointSide === ControlPointSideType.Random) { + // 随机选择一侧(与原来的行为一致) + sideMultiplier = Math.random() < 0.5 ? 1 : -1; + } else { + // 使用指定的侧面 + sideMultiplier = this.controlPointSide; + } + + // 根据控制点偏移系数和随机性计算控制点 + const distance = Vec3.distance(this._startPoint, this._endPoint); + const offset = distance * this.controlPointOffset; + const randomFactor = (Math.random() * 2 - 1) * this.controlPointRandomness; + + // 设置控制点 = 中点 + 垂直向量 * 偏移 * (1 + 随机因子) * 侧面乘数 + this._controlPoint.set( + midPoint.x + perpendicular.x * offset * (1 + randomFactor) * sideMultiplier, + midPoint.y + perpendicular.y * offset * (1 + randomFactor) * sideMultiplier, + 0 + ); + } + + /** + * 停止当前移动 + */ + stopMoving(): void { + this._isMoving = false; + } + + /** + * 计算二次贝塞尔曲线上的点 + */ + private _calculateQuadraticBezierPoint(t: number, p0: Vec3, p1: Vec3, p2: Vec3): Vec3 { + const u = 1 - t; + const tt = t * t; + const uu = u * u; + + const p = new Vec3(); + // p = (u^2 * p0) + (2 * u * t * p1) + (t^2 * p2) + Vec3.multiplyScalar(p, p0, uu); + const temp1 = new Vec3(); + Vec3.multiplyScalar(temp1, p1, 2 * u * t); + Vec3.add(p, p, temp1); + const temp2 = new Vec3(); + Vec3.multiplyScalar(temp2, p2, tt); + Vec3.add(p, p, temp2); + + return p; + } + + /** + * 计算二次贝塞尔曲线的切线(导数) + */ + private _calculateQuadraticBezierTangent(t: number, p0: Vec3, p1: Vec3, p2: Vec3): Vec3 { + + const u = 1 - t; + const tangent = new Vec3(); + + // tangent = 2 * (1 - t) * (p1 - p0) + 2 * t * (p2 - p1) + const term1 = new Vec3(); + Vec3.subtract(term1, p1, p0); + Vec3.multiplyScalar(term1, term1, 2 * u); + + const term2 = new Vec3(); + Vec3.subtract(term2, p2, p1); + Vec3.multiplyScalar(term2, term2, 2 * t); + + Vec3.add(tangent, term1, term2); + + return tangent; + } + + /** + * 应用缓动效果到t值 + * @param t 原始t值(0-1之间) + * @returns 应用缓动后的t值 + */ + private _applyEasing(t: number): number { + // 确保t在0-1范围内 + t = Math.max(0, Math.min(1, t)); + + // 使用tween.easing函数应用缓动 + switch (this.easing) { + case EasingType.linear: + return t; // 线性不需要额外处理 + case EasingType.smooth: + return t * t * (3 - 2 * t); // 平滑过渡 + case EasingType.fade: + return t * t * (3 - 2 * t); // 平滑过渡 + case EasingType.quadIn: + return t * t; // 二次方加速 + case EasingType.quadOut: + return t * (2 - t); // 二次方减速 + case EasingType.quadInOut: + return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; // 二次方加速然后减速 + case EasingType.quadOutIn: + return t < 0.5 ? 0.5 * (1 - Math.pow(-2 * t + 1, 2)) : 0.5 * Math.pow(2 * t - 1, 2) + 0.5; // 二次方减速然后加速 + case EasingType.cubicIn: + return t * t * t; // 三次方加速 + case EasingType.cubicOut: + return (--t) * t * t + 1; // 三次方减速 + case EasingType.cubicInOut: + return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1; // 三次方加速然后减速 + case EasingType.cubicOutIn: + return t < 0.5 ? 0.5 * ((t = t * 2 - 1) * t * t + 1) : 0.5 * (t = t * 2 - 1) * t * t + 0.5; // 三次方减速然后加速 + case EasingType.quartIn: + return t * t * t * t; // 四次方加速 + case EasingType.quartOut: + return 1 - (--t) * t * t * t; // 四次方减速 + case EasingType.quartInOut: + return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t; // 四次方加速然后减速 + case EasingType.quartOutIn: + return t < 0.5 ? 0.5 * (1 - Math.pow(-2 * t + 1, 4)) : 0.5 * Math.pow(2 * t - 1, 4) + 0.5; // 四次方减速然后加速 + case EasingType.quintIn: + return t * t * t * t * t; // 五次方加速 + case EasingType.quintOut: + return 1 + (--t) * t * t * t * t; // 五次方减速 + case EasingType.quintInOut: + return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t; // 五次方加速然后减速 + case EasingType.quintOutIn: + return t < 0.5 ? 0.5 * (1 - Math.pow(-2 * t + 1, 5)) : 0.5 * Math.pow(2 * t - 1, 5) + 0.5; // 五次方减速然后加速 + case EasingType.sineIn: + return 1 - Math.cos(t * Math.PI / 2); // 正弦加速 + case EasingType.sineOut: + return Math.sin(t * Math.PI / 2); // 正弦减速 + case EasingType.sineInOut: + return 0.5 * (1 - Math.cos(Math.PI * t)); // 正弦加速然后减速 + case EasingType.sineOutIn: + return t < 0.5 ? 0.5 * Math.sin(t * Math.PI) : 0.5 - 0.5 * Math.cos((t * 2 - 1) * Math.PI / 2); // 正弦减速然后加速 + case EasingType.circIn: + return 1 - Math.sqrt(1 - t * t); // 圆形加速 + case EasingType.circOut: + return Math.sqrt(1 - (t - 1) * (t - 1)); // 圆形减速 + case EasingType.circInOut: + return t < 0.5 + ? (1 - Math.sqrt(1 - 4 * t * t)) / 2 + : (Math.sqrt(1 - Math.pow(-2 * t + 2, 2)) + 1) / 2; // 圆形加速然后减速 + case EasingType.circOutIn: + return t < 0.5 ? 0.5 * Math.sqrt(1 - Math.pow(-2 * t + 1, 2)) : 0.5 * (2 - Math.sqrt(1 - Math.pow(2 * t - 1, 2))); // 圆形减速然后加速 + case EasingType.expoIn: + return t === 0 ? 0 : Math.pow(2, 10 * t - 10); // 指数加速 + case EasingType.expoOut: + return t === 1 ? 1 : 1 - Math.pow(2, -10 * t); // 指数减速 + case EasingType.expoInOut: + return t === 0 ? 0 : t === 1 ? 1 : t < 0.5 + ? Math.pow(2, 20 * t - 10) / 2 + : (2 - Math.pow(2, -20 * t + 10)) / 2; // 指数加速然后减速 + case EasingType.expoOutIn: + return t === 0 ? 0 : t === 1 ? 1 : t < 0.5 + ? 0.5 * (1 - Math.pow(2, -20 * t)) + : 0.5 * Math.pow(2, 20 * (t - 0.5) - 10) + 0.5; // 指数减速然后加速 + case EasingType.backIn: + const s = 1.70158; + return t * t * ((s + 1) * t - s); // 回弹加速 + case EasingType.backOut: + const s2 = 1.70158; + return (t = t - 1) * t * ((s2 + 1) * t + s2) + 1; // 回弹减速 + case EasingType.backInOut: + const s3 = 1.70158 * 1.525; + if (t < 0.5) { + return (t * 2) * (t * 2) * ((s3 + 1) * (t * 2) - s3) / 2; + } else { + return ((t * 2 - 2) * (t * 2 - 2) * ((s3 + 1) * (t * 2 - 2) + s3) + 2) / 2; + } // 回弹加速然后减速 + case EasingType.backOutIn: + const s4 = 1.70158; + return t < 0.5 + ? 0.5 * ((t = t * 2 - 1) * t * ((s4 + 1) * t + s4) + 1) + : 0.5 * (t = t * 2 - 1) * t * ((s4 + 1) * t - s4) + 0.5; // 回弹减速然后加速 + case EasingType.elasticIn: + return t === 0 ? 0 : t === 1 ? 1 : -Math.pow(2, 10 * (t - 1)) * Math.sin((t - 1.1) * 5 * Math.PI); // 弹性加速 + case EasingType.elasticOut: + return t === 0 ? 0 : t === 1 ? 1 : Math.pow(2, -10 * t) * Math.sin((t - 0.1) * 5 * Math.PI) + 1; // 弹性减速 + case EasingType.elasticInOut: + if (t === 0) return 0; + if (t === 1) return 1; + if (t < 0.5) { + return -0.5 * Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * Math.PI / 2.25); + } else { + return 0.5 * Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * Math.PI / 2.25) + 1; + } // 弹性加速然后减速 + case EasingType.elasticOutIn: + if (t === 0) return 0; + if (t === 1) return 1; + if (t < 0.5) { + return 0.5 * Math.pow(2, -20 * t) * Math.sin((20 * t - 0.5) * 5 * Math.PI) + 0.5; + } else { + return 0.5 * -Math.pow(2, 10 * (2 * t - 1.5)) * Math.sin((2 * t - 1.6) * 5 * Math.PI) + 0.5; + } // 弹性减速然后加速 + case EasingType.bounceIn: + return 1 - this._bounceOut(1 - t); // 弹跳加速 + case EasingType.bounceOut: + return this._bounceOut(t); // 弹跳减速 + case EasingType.bounceInOut: + return t < 0.5 + ? (1 - this._bounceOut(1 - 2 * t)) / 2 + : (1 + this._bounceOut(2 * t - 1)) / 2; // 弹跳加速然后减速 + case EasingType.bounceOutIn: + return t < 0.5 + ? this._bounceOut(t * 2) / 2 + : (1 - this._bounceOut(2 - 2 * t)) / 2 + 0.5; // 弹跳减速然后加速 + default: + return t; // 默认线性 + } + } + + /** + * 辅助函数:弹跳减速效果 + */ + private _bounceOut(t: number): number { + if (t < 1 / 2.75) { + return 7.5625 * t * t; + } else if (t < 2 / 2.75) { + return 7.5625 * (t -= 1.5 / 2.75) * t + 0.75; + } else if (t < 2.5 / 2.75) { + return 7.5625 * (t -= 2.25 / 2.75) * t + 0.9375; + } else { + return 7.5625 * (t -= 2.625 / 2.75) * t + 0.984375; + } + } + + /** + * 初始化Graphics组件 + */ + private _initGraphics(): void { + // 为每个MovingTarget实例创建唯一的轨迹节点名称,避免多个实例共享同一个轨迹节点 + const uniqueNodeName = `TrajectoryGraphics_${this.node.uuid}`; + + // 尝试查找已存在的轨迹节点(基于唯一ID) + let graphicsNode = this.node.parent?.getChildByName(uniqueNodeName); + + // 如果不存在,则创建新的轨迹节点 + if (!graphicsNode) { + graphicsNode = new Node(uniqueNodeName); + // 初始时先添加到场景中,但不设置父节点,会在_drawTrajectory中设置 + if (this.node.parent) { + this.node.parent.addChild(graphicsNode); + } else { + this.node.addChild(graphicsNode); + } + } + + // 获取或添加Graphics组件到节点 + this._graphics = graphicsNode.getComponent(Graphics); + if (!this._graphics) { + this._graphics = graphicsNode.addComponent(Graphics); + } + } + + /** + * 清除轨迹 + */ + public clearTrajectory(): void { + if (!this._graphics) return; + // 清除之前的轨迹 + this._graphics.clear(); + } + + /** + * 绘制轨迹 + */ + private _drawTrajectory(): void { + if (!this.showTrajectory) return; + + if (!this._graphics) return; + // 清除之前的轨迹 + this._graphics.clear(); + + // 设置轨迹样式 + this._graphics.lineWidth = this.trajectoryWidth; + this._graphics.strokeColor = this.trajectoryColor; + + // 获取Graphics所在节点 + const graphicsNode = this._graphics.node; + + // 将Graphics节点设置为与主节点的父节点相同,确保轨迹在世界坐标系中绘制 + if (this.node.parent) { + graphicsNode.parent = this.node.parent; + + // 移动到起点(世界坐标系中的实际位置) + this._graphics.moveTo(this._startPoint.x, this._startPoint.y); + + // 直接使用控制点和终点的世界坐标绘制贝塞尔曲线 + this._graphics.quadraticCurveTo( + this._controlPoint.x, this._controlPoint.y, + this._endPoint.x, this._endPoint.y + ); + } + + // 应用绘制 + this._graphics.stroke(); + } + + /** + * 平滑角度插值,确保选择最短路径旋转 + * @param currentAngle 当前角度 + * @param targetAngle 目标角度 + * @param smoothFactor 平滑系数(0-1),值越小越平滑 + * @returns 插值后的新角度 + */ + private _smoothAngle(currentAngle: number, targetAngle: number, smoothFactor: number): number { + // 确保平滑系数在有效范围内 + smoothFactor = Math.max(0.001, Math.min(1, smoothFactor)); + + // 标准化角度到 0-360 范围 + const normalizeAngle = (angle: number): number => { + angle = angle % 360; + return angle < 0 ? angle + 360 : angle; + }; + + // 标准化当前角度和目标角度 + const normCurrent = normalizeAngle(currentAngle); + const normTarget = normalizeAngle(targetAngle); + + // 计算最短路径旋转方向 + let delta = normTarget - normCurrent; + + // 如果角度差大于180度,选择另一个方向旋转(最短路径) + if (delta > 180) { + delta -= 360; + } else if (delta < -180) { + delta += 360; + } + + // 应用平滑系数进行插值 + return currentAngle + delta * smoothFactor; + } +} + + + diff --git a/assets/script/game/BezierMove/BezierMove.ts.meta b/assets/script/game/BezierMove/BezierMove.ts.meta new file mode 100644 index 00000000..19b7ff4d --- /dev/null +++ b/assets/script/game/BezierMove/BezierMove.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "f680d91a-831f-4f99-b7ea-b45e3adff51a", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/script/game/common/SingletonModuleComp.ts b/assets/script/game/common/SingletonModuleComp.ts index d83beb76..5a574ba4 100644 --- a/assets/script/game/common/SingletonModuleComp.ts +++ b/assets/script/game/common/SingletonModuleComp.ts @@ -2,6 +2,7 @@ import { VM } from "../../../../extensions/oops-plugin-framework/assets/libs/mod import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { Initialize } from "../initialize/Initialize"; import { GameMap } from "../map/GameMap"; +import { MissionData, MissionMons, Missions } from "./config/Mission"; // import { Role } from "../role/Role"; @@ -17,13 +18,6 @@ export class SingletonModuleComp extends ecs.Comp { status:0, //0:未开始 1:进行中 2:胜利 3:失败 play:false, pause:false, - is_victory:false, - is_defeat:false, - is_battle:false, - lv:0, - victory:0, - mskill:6001, - mmskill:6002, }; fight_heros=[] mheros:any = []; @@ -41,45 +35,11 @@ export class SingletonModuleComp extends ecs.Comp { game_over:false, game_pause:false, mission_data:{ - gold:10,//金币 - refresh_gold:1,//刷新金币 - refrsh_time:1, //刷新时间 - call_gold:3,//召唤金币 - add_gold:1,//金币增加 - change_gold:1,//金币变化 - exp:0,//经验 - skp:0,//技能点 - box:0,//宝箱 - energy:0,//能量 - hp:0,//血量 - ap:0,//攻击 + }, - mission:{ - once:6, //每波刷新怪物数量 - total:1, //总怪物数 - exp:0, - exp_max:100, - mexp:0, - mexp_max:100, - drop:0, - hp:0, - ap:0, - def:0, - crit:0, - dodge:0, - dead:0, - reward_num:0, //怪物死亡数 - reward_gold:0, - reward_exp:0, - }, - gold:{num:999999,x1:0}, - exp:{num:1000,x1:0}, - skp:{num:2000,x1:0}, //技能升级点数 - energy:{num:10,x1:0}, - box:{num:10,x1:0}, - }; vmAdd() { + this.vmdata.mission_data=MissionData VM.add(this.vmdata, "data"); } diff --git a/assets/script/game/common/config/Mission.ts b/assets/script/game/common/config/Mission.ts index 6e527d55..70a137a8 100644 --- a/assets/script/game/common/config/Mission.ts +++ b/assets/script/game/common/config/Mission.ts @@ -5,6 +5,7 @@ export const MonsetList = { } } + export const BossList = { 1:{ 1:[5001], @@ -22,8 +23,6 @@ export const Missions = [ [5213,5214,5215,5216,5217,5218], [5225,5226,5227], ] - - export const MissionReward = { 1:[1001,1002,1003,1004,1005,1006,1021,1022,1023,1024,1025,1026,1027,1028], 2:[1001,1002,1003,1004,1005,1006,1021,1022,1023,1024,1025,1026,1027,1028], @@ -45,11 +44,11 @@ export const MBSet = { crit_cost:2, dodge_cost:2, } -export const MissStatus = { +export const MissionStatus = { ready:0, - playing:1, - pause:2, - choose:3, + ready_skill_select:1, + ready_hero_select:2, + playing:3, end:4, } export enum FightSet { @@ -66,3 +65,18 @@ export enum FightSet { AP_UPDATE_RATE=100, AP_CHANGE_RATE=0, } +export const MissionData = { + gold:10,//金币 + refresh_gold:1,//刷新金币 + refrsh_time:1, //刷新时间 + call_gold:3,//召唤金币 + add_gold:1,//金币增加 + change_gold:1,//金币变化 + exp:0,//经验 + skp:0,//技能点 + box:0,//宝箱 + energy:0,//能量 + hp:0,//血量 + ap:0,//攻击 + lv:0, +} diff --git a/assets/script/game/map/MissionComp.ts b/assets/script/game/map/MissionComp.ts index d324120b..f9356a55 100644 --- a/assets/script/game/map/MissionComp.ts +++ b/assets/script/game/map/MissionComp.ts @@ -3,15 +3,11 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; import { smc } from "../common/SingletonModuleComp"; import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops"; -import { Missions} from "../common/config/Mission"; +import { MissionData, Missions, MissionStatus} from "../common/config/Mission"; import { Timer } from "../../../../extensions/oops-plugin-framework/assets/core/common/timer/Timer"; -import { VictoryComp } from "./VictoryComp"; -import { CardControllerComp } from "./CardController"; import { GameEvent } from "../common/config/GameEvent"; import { HeroViewComp } from "../hero/HeroViewComp"; import { Hero } from "../hero/Hero"; -import { TimerManager } from "db://oops-framework/core/common/timer/TimerManager"; -import { HeroList } from "../common/config/heroSet"; const { ccclass, property } = _decorator; /** 视图层对象 */ @@ -41,6 +37,7 @@ export class MissionComp extends CCComp { this.on(GameEvent.MissionStart,this.mission_start,this) this.on(GameEvent.FightEnd,this.fight_end,this) this.on(GameEvent.MissionEnd,this.mission_end,this) + this.on(GameEvent.CardsClose,this.after_used_skill_card,this) } protected update(dt: number): void { @@ -52,12 +49,9 @@ export class MissionComp extends CCComp { } } - - - mission_start(){ - /* todo 关卡设定完善*/ - console.log("战斗开始 关卡怪物:",Missions[smc.mission.lv]) + async mission_start(){ + smc.mission.status=MissionStatus.ready this.node.active=true this.data_init() this.hart_hero_load() @@ -72,17 +66,38 @@ export class MissionComp extends CCComp { to_hero_skill_select(){ console.log("英雄技能选择") oops.message.dispatchEvent(GameEvent.HeroSkillSelect) + smc.mission.status=MissionStatus.ready_skill_select + } + after_used_skill_card(){ + switch(smc.mission.status){ + case MissionStatus.ready_skill_select: + console.log("next to_hero_select") + this.scheduleOnce(()=>{ + this.to_hero_select() + },0.3) + + break + case MissionStatus.ready_hero_select: + console.log("netx to_fight") + this.to_fight() + break + case MissionStatus.playing: + break + } } to_hero_select(){ + smc.mission.status=MissionStatus.ready_hero_select oops.message.dispatchEvent(GameEvent.HeroSelect) } to_fight(){ + smc.mission.status=MissionStatus.playing oops.message.dispatchEvent(GameEvent.FightStart) } to_end_fight(){ + smc.mission.status=MissionStatus.end oops.message.dispatchEvent(GameEvent.FightEnd) } @@ -101,12 +116,9 @@ export class MissionComp extends CCComp { data_init(){ //局内数据初始化 console.log("局内数据初始化") - this.GlodAddTimer=new Timer(smc.vmdata.mission_data.refrsh_time) - smc.mission.status=1 smc.mission.play = true; - smc.mission.is_victory=false - smc.mission.is_defeat=false - smc.vmdata.mission_data ={...smc.vmdata.mission_data} + smc.vmdata.mission_data =MissionData + this.GlodAddTimer=new Timer(smc.vmdata.mission_data.refrsh_time) } //角色初始化 @@ -129,8 +141,6 @@ export class MissionComp extends CCComp { } - - private cleanComponents() { ecs.query(ecs.allOf(HeroViewComp)).forEach(entity => {entity.remove(HeroViewComp);entity.destroy()}); }