From 0d88556089aff1485e9f5fa92a733d883e9f77ec Mon Sep 17 00:00:00 2001 From: wvellichor Date: Sun, 18 Jan 2026 01:53:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(skill)=20=E6=B7=BB=E5=8A=A03=E6=8A=80?= =?UTF-8?q?=E8=83=BD=E6=8A=80=E8=83=BD=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scenes/testScenes/AttackSkillTestScene.js | 169 +++++++++++++++++++++- 1 file changed, 161 insertions(+), 8 deletions(-) diff --git a/scenes/testScenes/AttackSkillTestScene.js b/scenes/testScenes/AttackSkillTestScene.js index c855a1b..d90c396 100644 --- a/scenes/testScenes/AttackSkillTestScene.js +++ b/scenes/testScenes/AttackSkillTestScene.js @@ -283,7 +283,7 @@ export default class AttackSkillTestScene extends Phaser.Scene { } // 相机锁定逻辑:如果有锁定状态且有当前控制的角色,则让相机跟随角色 - import('../systems/ControlMode.js').then(mod => { + import('../../systems/ControlMode.js').then(mod => { if (mod.cameraLocked && this.currentlyControlled) { this.cameras.main.startFollow(this.currentlyControlled); } else { @@ -501,7 +501,7 @@ export default class AttackSkillTestScene extends Phaser.Scene { this.skillWheel.skillInfo = { 1: { key: 'Q', color: 0x00ff00 }, // 扔出傀儡 2: { key: 'W', color: 0x00ffff }, // 二技能:飞镖攻击 - 3: { key: 'E', color: 0xff00ff }, // 占位 + 3: { key: 'E', color: 0xff00ff }, // 三技能:十字斩 4: { key: 'R', color: 0xffff00 } // 本体移动 }; } else if (this.currentlyControlled && this.currentlyControlled.type === 'diaochan') { @@ -746,6 +746,9 @@ export default class AttackSkillTestScene extends Phaser.Scene { case 2: // 技能2:扇形飞镖攻击 this.castFanDartSkill(); break; + case 3: // 技能3:十字斩 + this.castCrossSlashSkill(); + break; case 4: // 技能4:本体向技能指向方向移动 // 确保是本体在控制 if (!this.isControllingPuppet) { @@ -793,17 +796,17 @@ export default class AttackSkillTestScene extends Phaser.Scene { // 计算技能释放角度 const skillAngle = Math.atan2(directionY, directionX); - // 扇形角度范围:30度(转换为弧度) - const fanAngle = Phaser.Math.DegToRad(30); + // 扇形角度范围:45度(转换为弧度) + const fanAngle = Phaser.Math.DegToRad(45); // 飞镖数量 - const dartCount = 5; + const dartCount = 4; // 飞镖速度 const dartSpeed = 1000; // 飞镖飞行距离 - const dartDistance = 300; + const dartDistance = 400; // 计算每个飞镖的角度间隔 const angleStep = fanAngle / (dartCount - 1); @@ -843,6 +846,101 @@ export default class AttackSkillTestScene extends Phaser.Scene { } } + /** + * 释放十字斩技能 + */ + castCrossSlashSkill() { + if (!this.currentlyControlled) return; + + // 计算技能释放方向(基于技能轮盘中心到指针的相对方向) + const pointer = this.input.activePointer; + const directionX = pointer.x - this.skillWheel.centerX; + const directionY = pointer.y - this.skillWheel.centerY; + + // 计算技能释放角度 + const skillAngle = Math.atan2(directionY, directionX); + + // 计算归一化方向向量 + const distance = Math.sqrt(directionX * directionX + directionY * directionY); + let normalizedX = 0; + let normalizedY = 0; + if (distance > 0) { + normalizedX = directionX / distance; + normalizedY = directionY / distance; + } + + // 十字斩放置距离范围 + const minDistance = 0; // 最小距离(角色自身位置) + const maxDistance = 200; // 最大距离 + + // 计算轮盘按钮与中心的距离百分比(相对于轮盘半径) + const distancePercentage = Math.min(distance / this.skillWheel.radius, 1); + + // 根据距离百分比计算十字斩实际释放距离 + const crossSlashDistance = minDistance + (maxDistance - minDistance) * distancePercentage; + // 本体反向位移距离(固定值) + const bodyDisplacementDistance = 100; + + // 计算十字斩位置 + const crossSlashX = this.currentlyControlled.x + normalizedX * crossSlashDistance; + const crossSlashY = this.currentlyControlled.y + normalizedY * crossSlashDistance; + + // 创建十字斩效果 + this.createCrossSlashEffect(crossSlashX, crossSlashY, skillAngle); + + // 本体向相反方向位移 + const bodyDisplacementX = -normalizedX * bodyDisplacementDistance; + const bodyDisplacementY = -normalizedY * bodyDisplacementDistance; + this.currentlyControlled.x += bodyDisplacementX; + this.currentlyControlled.y += bodyDisplacementY; + this.currentlyControlled.setVelocity(0, 0); + } + + /** + * 创建十字斩视觉效果 + */ + createCrossSlashEffect(x, y, angle) { + // 创建十字斩图形 + const crossSlash = this.add.graphics(); + crossSlash.setScrollFactor(1); + crossSlash.setDepth(50); + + // 十字斩尺寸 + const crossSize = 80; + + // 设置十字斩位置 + crossSlash.setPosition(x, y); + + // 绘制十字(相对于位置点) + crossSlash.lineStyle(4, 0xff00ff, 1); + // 水平线 + crossSlash.beginPath(); + crossSlash.moveTo(-crossSize/2, 0); + crossSlash.lineTo(crossSize/2, 0); + crossSlash.strokePath(); + // 垂直线 + crossSlash.beginPath(); + crossSlash.moveTo(0, -crossSize/2); + crossSlash.lineTo(0, crossSize/2); + crossSlash.strokePath(); + + // 旋转十字斩以匹配技能方向(调整角度使连线位于夹角中间) + crossSlash.rotation = angle - Math.PI/4; + + // 十字斩持续时间 + const duration = 1000; + + // 淡出效果 + this.tweens.add({ + targets: crossSlash, + alpha: 0, + duration: duration, + onComplete: () => { + crossSlash.destroy(); + } + }); + } + /** * 更新技能预览效果 */ @@ -895,6 +993,61 @@ export default class AttackSkillTestScene extends Phaser.Scene { this.skillPreview.strokeCircle(targetX, targetY, 15); this.skillPreview.fillStyle(0x00ff00, 0.2); this.skillPreview.fillCircle(targetX, targetY, 15); + } else if (this.skillWheel.activeSkill === 3 && !this.isControllingPuppet) { + // 三技能:十字斩预览 + const minDistance = 0; // 最小距离(角色自身位置) + const maxDistance = 200; // 最大距离 + const maxBodyDisplacementDistance = 100; // 最大本体位移距离 + + // 计算轮盘按钮与中心的距离百分比(相对于轮盘半径) + const distancePercentage = Math.min(distance / this.skillWheel.radius, 1); + + // 根据距离百分比计算十字斩实际释放距离 + const crossSlashDistance = minDistance + (maxDistance - minDistance) * distancePercentage; + // 本体反向位移距离(与十字斩释放距离成比例) + const bodyDisplacementDistance = maxBodyDisplacementDistance * distancePercentage; + + // 计算十字斩位置 + const crossSlashX = this.currentlyControlled.x + normalizedX * crossSlashDistance; + const crossSlashY = this.currentlyControlled.y + normalizedY * crossSlashDistance; + + // 计算本体位移后的位置 + const bodyDisplacementX = -normalizedX * bodyDisplacementDistance; + const bodyDisplacementY = -normalizedY * bodyDisplacementDistance; + const bodyEndX = this.currentlyControlled.x + bodyDisplacementX; + const bodyEndY = this.currentlyControlled.y + bodyDisplacementY; + + // 绘制十字斩预览 + this.skillPreview.lineStyle(4, 0xff00ff, 0.5); + // 计算旋转后的四个端点坐标(调整角度使连线位于夹角中间) + const crossSize = 40; + const adjustedAngle = skillAngle - Math.PI/4; + // 水平线左端点 + const hLeftX = crossSlashX + Math.cos(adjustedAngle - Math.PI/2) * crossSize; + const hLeftY = crossSlashY + Math.sin(adjustedAngle - Math.PI/2) * crossSize; + // 水平右端点 + const hRightX = crossSlashX + Math.cos(adjustedAngle + Math.PI/2) * crossSize; + const hRightY = crossSlashY + Math.sin(adjustedAngle + Math.PI/2) * crossSize; + // 垂直线上端点 + const vTopX = crossSlashX + Math.cos(adjustedAngle) * crossSize; + const vTopY = crossSlashY + Math.sin(adjustedAngle) * crossSize; + // 垂直线下端点 + const vBottomX = crossSlashX + Math.cos(adjustedAngle + Math.PI) * crossSize; + const vBottomY = crossSlashY + Math.sin(adjustedAngle + Math.PI) * crossSize; + + // 绘制水平线 + this.skillPreview.beginPath(); + this.skillPreview.moveTo(hLeftX, hLeftY); + this.skillPreview.lineTo(hRightX, hRightY); + this.skillPreview.strokePath(); + // 绘制垂直线 + this.skillPreview.beginPath(); + this.skillPreview.moveTo(vTopX, vTopY); + this.skillPreview.lineTo(vBottomX, vBottomY); + this.skillPreview.strokePath(); + + // 绘制十字斩方向 + // 移除本体与技能的连线 } else if (this.skillWheel.activeSkill === 4 && !this.isControllingPuppet) { // 四技能:本体移动预览 const maxDistance = 200; @@ -917,8 +1070,8 @@ export default class AttackSkillTestScene extends Phaser.Scene { this.skillPreview.fillCircle(targetX, targetY, 15); } else if (this.skillWheel.activeSkill === 2 && !this.isControllingPuppet) { // 二技能:扇形飞镖攻击预览 - // 扇形角度范围:30度(转换为弧度) - const fanAngle = Phaser.Math.DegToRad(30); + // 扇形角度范围:45度(转换为弧度) + const fanAngle = Phaser.Math.DegToRad(45); // 飞镖数量 const dartCount = 5;