feat(skill): 重做普攻弹道逻辑,优化攻击命中表现
1. 新增atk_ci普攻预制体,替换原有的atk_light预制体配置 2. 调整普攻预制体的位置、缩放属性,更新技能配置的sp名 3. 重构施法目标坐标计算,修正Y轴高度偏移以命中目标中心 4. 优化线性弹道移动逻辑,统一处理弹道延长和旋转计算 5. 更新攻击动画的帧时长和精灵贴图资源
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
"speed": 1,
|
||||
"wrapMode": 2,
|
||||
"enableTrsBlending": false,
|
||||
"_duration": 0.3,
|
||||
"_duration": 0.13333333333333333,
|
||||
"_hash": 500763545,
|
||||
"_tracks": [
|
||||
{
|
||||
@@ -71,48 +71,23 @@
|
||||
0,
|
||||
0.03333333333333333,
|
||||
0.06666666666666667,
|
||||
0.1,
|
||||
0.13333333333333333,
|
||||
0.16666666666666666,
|
||||
0.2,
|
||||
0.23333333333333334,
|
||||
0.26666666666666666
|
||||
0.1
|
||||
],
|
||||
"_values": [
|
||||
{
|
||||
"__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@dce69",
|
||||
"__uuid__": "3d46f945-3f07-477e-a95a-b49557d552c6@c85a2",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
{
|
||||
"__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@f3a1e",
|
||||
"__uuid__": "3d46f945-3f07-477e-a95a-b49557d552c6@1526a",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
{
|
||||
"__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@d5671",
|
||||
"__uuid__": "3d46f945-3f07-477e-a95a-b49557d552c6@fa8fc",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
{
|
||||
"__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@ad18c",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
{
|
||||
"__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@7e2c5",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
{
|
||||
"__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@dd096",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
{
|
||||
"__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@5f8fc",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
{
|
||||
"__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@386fd",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
{
|
||||
"__uuid__": "2423272e-e63b-4736-b15b-30b40cf98a23@d4c73",
|
||||
"__uuid__": "3d46f945-3f07-477e-a95a-b49557d552c6@0d06a",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
}
|
||||
]
|
||||
|
||||
371
assets/resources/game/skill/atk/atk_ci.prefab
Normal file
371
assets/resources/game/skill/atk/atk_ci.prefab
Normal file
@@ -0,0 +1,371 @@
|
||||
[
|
||||
{
|
||||
"__type__": "cc.Prefab",
|
||||
"_name": "atk_ci",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_native": "",
|
||||
"data": {
|
||||
"__id__": 1
|
||||
},
|
||||
"optimizationPolicy": 0,
|
||||
"persistent": false
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "atk_ci",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": null,
|
||||
"_children": [
|
||||
{
|
||||
"__id__": 2
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 8
|
||||
},
|
||||
{
|
||||
"__id__": 10
|
||||
},
|
||||
{
|
||||
"__id__": 12
|
||||
},
|
||||
{
|
||||
"__id__": 14
|
||||
},
|
||||
{
|
||||
"__id__": 16
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 18
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "Node",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 3
|
||||
},
|
||||
{
|
||||
"__id__": 5
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 7
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 7.98,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 2
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 4
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 64,
|
||||
"height": 64
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "93pNmvtQlLSqtTgIepyEmA"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 2
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 6
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
"_dstBlendFactor": 4,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "3d46f945-3f07-477e-a95a-b49557d552c6@c85a2",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
"_type": 0,
|
||||
"_fillType": 0,
|
||||
"_sizeMode": 1,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_useGrayscale": false,
|
||||
"_atlas": {
|
||||
"__uuid__": "3d46f945-3f07-477e-a95a-b49557d552c6",
|
||||
"__expectedType__": "cc.SpriteAtlas"
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "12eKc8gltBz50frJCS5+ww"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "3arqAMBz1MvoXBzeDaL5M/",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 9
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 50,
|
||||
"height": 50
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "63NP9yq3hEUKD/OZZZ5t7x"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Animation",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 11
|
||||
},
|
||||
"playOnLoad": true,
|
||||
"_clips": [
|
||||
{
|
||||
"__uuid__": "c09c3e6a-dd75-47ec-9db8-cd72c0f9fc59",
|
||||
"__expectedType__": "cc.AnimationClip"
|
||||
}
|
||||
],
|
||||
"_defaultClip": {
|
||||
"__uuid__": "c09c3e6a-dd75-47ec-9db8-cd72c0f9fc59",
|
||||
"__expectedType__": "cc.AnimationClip"
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "c2RDvksalG2acL3tyGCY0t"
|
||||
},
|
||||
{
|
||||
"__type__": "57aabs7TE1J5obTAZczc+64",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 13
|
||||
},
|
||||
"atk_x": 10,
|
||||
"atk_y": 15,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "60LInmZXxDtKu79AshRG9j"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.RigidBody2D",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 15
|
||||
},
|
||||
"enabledContactListener": true,
|
||||
"bullet": false,
|
||||
"awakeOnLoad": true,
|
||||
"_group": 1,
|
||||
"_type": 1,
|
||||
"_allowSleep": false,
|
||||
"_gravityScale": 1,
|
||||
"_linearDamping": 0,
|
||||
"_angularDamping": 0,
|
||||
"_linearVelocity": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_angularVelocity": 0,
|
||||
"_fixedRotation": false,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "e1yBA625RLwLhzo6bLYW7j"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.BoxCollider2D",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 17
|
||||
},
|
||||
"tag": 0,
|
||||
"_group": 1,
|
||||
"_density": 1,
|
||||
"_sensor": true,
|
||||
"_friction": 0.2,
|
||||
"_restitution": 0,
|
||||
"_offset": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_size": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 50,
|
||||
"height": 50
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "43ZDJfXX9AX73gyytKQZWm"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "c46/YsCPVOJYA4mWEpNYRx",
|
||||
"instance": null,
|
||||
"targetOverrides": null
|
||||
}
|
||||
]
|
||||
13
assets/resources/game/skill/atk/atk_ci.prefab.meta
Normal file
13
assets/resources/game/skill/atk/atk_ci.prefab.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "1.1.50",
|
||||
"importer": "prefab",
|
||||
"imported": true,
|
||||
"uuid": "6954a335-aa5e-4fb5-b0ad-64af6f0f4da1",
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"syncNodeName": "atk_ci"
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": -37.68,
|
||||
"x": 7.98,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
@@ -108,8 +108,8 @@
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0.8,
|
||||
"y": 1.8,
|
||||
"x": 0.5,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
@@ -282,7 +282,6 @@
|
||||
},
|
||||
"atk_x": 10,
|
||||
"atk_y": 15,
|
||||
"debugMode": true,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
|
||||
@@ -172,7 +172,7 @@ export const SkillUpList = {
|
||||
export const SkillSet: Record<number, SkillConfig> = {
|
||||
// ========== 基础技能 ==========
|
||||
6001: {
|
||||
uuid:6001,name:"普通攻击",sp_name:"atk",icon:"1026",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk",
|
||||
uuid:6001,name:"普通攻击",sp_name:"atk_ci",icon:"1026",TGroup:TGroup.Enemy,readyAnm:"",endAnm:"",act:"atk",
|
||||
DTType:DTType.single,ap:100,hit_count:1,hitcd:0.2,speed:720,with:0,ready:0.2,EAnm:0,DAnm:"",IType:IType.Melee,
|
||||
RType:RType.linear,EType:EType.collision,buffs:[],info:"造成攻击力100%的伤害",
|
||||
},
|
||||
|
||||
@@ -679,9 +679,22 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
|
||||
/** 生成沿目标方向的施法目标坐标 */
|
||||
private buildEnemyCastTargetPos(caster: HeroViewComp, target: HeroViewComp, castRange: number): Vec3 {
|
||||
const casterPos = caster.node.position;
|
||||
const targetPos = target.node.position;
|
||||
const direction = targetPos.x >= casterPos.x ? 1 : -1;
|
||||
return new Vec3(casterPos.x + direction * castRange, casterPos.y, casterPos.z);
|
||||
// 直接返回目标的真实坐标,保留其 Y 轴信息,确保能向目标真实所在位置发射
|
||||
// 考虑到目前角色的 y 坐标都是脚底(碰撞体底部),为了命中身体中心,给目标 y 加上高度的一半
|
||||
let halfHeight = 0;
|
||||
if (target.node) {
|
||||
const transform = target.node.getComponent('cc.UITransform') as any;
|
||||
if (transform) {
|
||||
halfHeight = transform.height / 2;
|
||||
} else {
|
||||
halfHeight = 40; // 如果没有 UITransform,给一个默认高度偏移
|
||||
}
|
||||
}
|
||||
|
||||
const pos = target.node.position.clone();
|
||||
pos.y += halfHeight;
|
||||
|
||||
// 至于最终投射物是否要飞出屏幕(例如线性弹道延长至 +-500),由 SMoveSystem 统一处理
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,31 +64,46 @@ export class SMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
|
||||
switch(moveComp.runType) {
|
||||
case RType.linear:
|
||||
// linear类型:根据atk_x和atk_y调整位置
|
||||
// linear类型:根据atk_x和atk_y调整起始位置
|
||||
const adjustedStartPos = v3(
|
||||
moveComp.startPos.x + moveComp.atk_x,
|
||||
moveComp.startPos.x + moveComp.atk_x * moveComp.scale,
|
||||
moveComp.startPos.y + moveComp.atk_y,
|
||||
moveComp.startPos.z
|
||||
);
|
||||
const adjustedTargetPos = v3(
|
||||
moveComp.targetPos.x + moveComp.atk_x,
|
||||
moveComp.targetPos.y + moveComp.atk_y,
|
||||
|
||||
const originTargetPos = v3(
|
||||
moveComp.targetPos.x,
|
||||
moveComp.targetPos.y,
|
||||
moveComp.targetPos.z
|
||||
);
|
||||
|
||||
// 如果开启水平移动开关,强制目标Y等于起点Y
|
||||
if (moveComp.isHorizontal) {
|
||||
adjustedTargetPos.y = adjustedStartPos.y;
|
||||
const direction = new Vec3();
|
||||
Vec3.subtract(direction, originTargetPos, adjustedStartPos);
|
||||
|
||||
// 延长终止点,统一消亡点的x坐标为 +-500
|
||||
const targetX = moveComp.scale > 0 ? 500 : -500;
|
||||
let targetY = originTargetPos.y;
|
||||
|
||||
if (Math.abs(direction.x) > 0.01) {
|
||||
const slope = direction.y / direction.x;
|
||||
targetY = adjustedStartPos.y + slope * (targetX - adjustedStartPos.x);
|
||||
}
|
||||
|
||||
const adjustedTargetPos = v3(
|
||||
targetX,
|
||||
targetY,
|
||||
originTargetPos.z
|
||||
);
|
||||
|
||||
moveComp.startPos.set(adjustedStartPos);
|
||||
moveComp.targetPos.set(adjustedTargetPos);
|
||||
node.setPosition(adjustedStartPos);
|
||||
|
||||
// 设置旋转角度
|
||||
const direction = new Vec3();
|
||||
Vec3.subtract(direction, moveComp.targetPos, moveComp.startPos);
|
||||
if (direction.length() > 0.01) {
|
||||
const angle = Math.atan2(direction.y, direction.x) * (180 / Math.PI);
|
||||
const dirForAngle = new Vec3();
|
||||
Vec3.subtract(dirForAngle, adjustedTargetPos, adjustedStartPos);
|
||||
if (dirForAngle.length() > 0.01) {
|
||||
const angle = Math.atan2(dirForAngle.y, dirForAngle.x) * (180 / Math.PI);
|
||||
node.angle = angle;
|
||||
}
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user