feat(英雄): 优化英雄移动和碰撞逻辑
fix由于 setScale 会影响物理判断,造成玩家角色多次被攻击触发回调 - 添加英雄移动方向缓存避免频繁转向 - 优化英雄碰撞器初始状态管理 - 修复英雄后退动画重复触发问题 - 调整部分英雄prefab的碰撞组和传感器设置
This commit is contained in:
@@ -991,7 +991,7 @@
|
|||||||
"node": {
|
"node": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": false,
|
"_enabled": true,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 62
|
"__id__": 62
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -991,7 +991,7 @@
|
|||||||
"node": {
|
"node": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": false,
|
"_enabled": true,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 62
|
"__id__": 62
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -991,7 +991,7 @@
|
|||||||
"node": {
|
"node": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": false,
|
"_enabled": true,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 62
|
"__id__": 62
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -961,7 +961,7 @@
|
|||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 60
|
"__id__": 60
|
||||||
},
|
},
|
||||||
"enabledContactListener": true,
|
"enabledContactListener": false,
|
||||||
"bullet": false,
|
"bullet": false,
|
||||||
"awakeOnLoad": true,
|
"awakeOnLoad": true,
|
||||||
"_group": 4,
|
"_group": 4,
|
||||||
@@ -991,7 +991,7 @@
|
|||||||
"node": {
|
"node": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": false,
|
"_enabled": true,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 62
|
"__id__": 62
|
||||||
},
|
},
|
||||||
@@ -1009,7 +1009,7 @@
|
|||||||
"_size": {
|
"_size": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 49.3,
|
"width": 49.3,
|
||||||
"height": 72.9
|
"height": 60.9
|
||||||
},
|
},
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -991,7 +991,7 @@
|
|||||||
"node": {
|
"node": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": false,
|
"_enabled": true,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 62
|
"__id__": 62
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -896,8 +896,8 @@
|
|||||||
},
|
},
|
||||||
"_contentSize": {
|
"_contentSize": {
|
||||||
"__type__": "cc.Size",
|
"__type__": "cc.Size",
|
||||||
"width": 80,
|
"width": 60,
|
||||||
"height": 8
|
"height": 80
|
||||||
},
|
},
|
||||||
"_anchorPoint": {
|
"_anchorPoint": {
|
||||||
"__type__": "cc.Vec2",
|
"__type__": "cc.Vec2",
|
||||||
@@ -991,7 +991,7 @@
|
|||||||
"node": {
|
"node": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": false,
|
"_enabled": true,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 62
|
"__id__": 62
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -991,7 +991,7 @@
|
|||||||
"node": {
|
"node": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": false,
|
"_enabled": true,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 62
|
"__id__": 62
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -988,12 +988,12 @@
|
|||||||
"node": {
|
"node": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": false,
|
"_enabled": true,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 62
|
"__id__": 62
|
||||||
},
|
},
|
||||||
"tag": 0,
|
"tag": 0,
|
||||||
"_group": 4,
|
"_group": 2,
|
||||||
"_density": 1,
|
"_density": 1,
|
||||||
"_sensor": true,
|
"_sensor": true,
|
||||||
"_friction": 0.2,
|
"_friction": 0.2,
|
||||||
|
|||||||
@@ -991,12 +991,12 @@
|
|||||||
"node": {
|
"node": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": false,
|
"_enabled": true,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 62
|
"__id__": 62
|
||||||
},
|
},
|
||||||
"tag": 0,
|
"tag": 0,
|
||||||
"_group": 4,
|
"_group": 2,
|
||||||
"_density": 1,
|
"_density": 1,
|
||||||
"_sensor": true,
|
"_sensor": true,
|
||||||
"_friction": 0.2,
|
"_friction": 0.2,
|
||||||
|
|||||||
@@ -991,7 +991,7 @@
|
|||||||
"node": {
|
"node": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": false,
|
"_enabled": true,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 62
|
"__id__": 62
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -991,14 +991,14 @@
|
|||||||
"node": {
|
"node": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_enabled": false,
|
"_enabled": true,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 62
|
"__id__": 62
|
||||||
},
|
},
|
||||||
"tag": 0,
|
"tag": 0,
|
||||||
"_group": 2,
|
"_group": 2,
|
||||||
"_density": 1,
|
"_density": 1,
|
||||||
"_sensor": false,
|
"_sensor": true,
|
||||||
"_friction": 0.2,
|
"_friction": 0.2,
|
||||||
"_restitution": 0,
|
"_restitution": 0,
|
||||||
"_offset": {
|
"_offset": {
|
||||||
|
|||||||
@@ -513,7 +513,7 @@
|
|||||||
"tag": 0,
|
"tag": 0,
|
||||||
"_group": 1,
|
"_group": 1,
|
||||||
"_density": 1,
|
"_density": 1,
|
||||||
"_sensor": false,
|
"_sensor": true,
|
||||||
"_friction": 0.2,
|
"_friction": 0.2,
|
||||||
"_restitution": 0,
|
"_restitution": 0,
|
||||||
"_offset": {
|
"_offset": {
|
||||||
|
|||||||
9
assets/resources/game/skill/ready.meta
Normal file
9
assets/resources/game/skill/ready.meta
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "1.2.0",
|
||||||
|
"importer": "directory",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "e44e387b-e119-4ea3-8c61-90be55888ce5",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas} from "cc";
|
import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas, BoxCollider2D} from "cc";
|
||||||
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
@@ -47,6 +47,8 @@ export class Hero extends ecs.Entity {
|
|||||||
var node = instantiate(prefab);
|
var node = instantiate(prefab);
|
||||||
var scene = smc.map.MapView.scene;
|
var scene = smc.map.MapView.scene;
|
||||||
node.parent = scene.entityLayer!.node!
|
node.parent = scene.entityLayer!.node!
|
||||||
|
const collider = node.getComponent(BoxCollider2D);
|
||||||
|
if (collider) collider.enabled = false; // 先禁用
|
||||||
node.setPosition(pos)
|
node.setPosition(pos)
|
||||||
// console.log("hero load",pos)
|
// console.log("hero load",pos)
|
||||||
var hv = node.getComponent(HeroViewComp)!;
|
var hv = node.getComponent(HeroViewComp)!;
|
||||||
|
|||||||
@@ -15,11 +15,14 @@ export class HeroMoveComp extends ecs.Comp {
|
|||||||
targetX: number = 0;
|
targetX: number = 0;
|
||||||
/** 是否处于移动状态 */
|
/** 是否处于移动状态 */
|
||||||
moving: boolean = true;
|
moving: boolean = true;
|
||||||
|
/** 当前朝向缓存:避免频繁setScale */
|
||||||
|
currentFacing: number = 1;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.direction = 1;
|
this.direction = 1;
|
||||||
this.targetX = 0;
|
this.targetX = 0;
|
||||||
this.moving = true;
|
this.moving = true;
|
||||||
|
this.currentFacing = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,12 +76,10 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
|||||||
// 根据敌人位置调整移动方向和朝向
|
// 根据敌人位置调整移动方向和朝向
|
||||||
if (enemyX > currentX) {
|
if (enemyX > currentX) {
|
||||||
move.direction = 1; // 向右移动
|
move.direction = 1; // 向右移动
|
||||||
view.node.setScale(1, 1, 1); // 面向右侧
|
this.setFacing(view, move, 1); // 🔥 使用优化的转向方法
|
||||||
view.node.getChildByName("top").setScale(1, 1, 1); // 面向右侧
|
|
||||||
} else {
|
} else {
|
||||||
move.direction = -1; // 向左移动
|
move.direction = -1; // 向左移动
|
||||||
view.node.setScale(-1, 1, 1); // 面向左侧
|
this.setFacing(view, move, -1); // 🔥 使用优化的转向方法
|
||||||
view.node.getChildByName("top").setScale(-1, 1, 1); // 面向左侧
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 继续向敌人方向移动
|
// 继续向敌人方向移动
|
||||||
@@ -112,14 +113,8 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
|||||||
const delta = (model.Attrs[Attrs.SPEED]/3) * this.dt * direction;
|
const delta = (model.Attrs[Attrs.SPEED]/3) * this.dt * direction;
|
||||||
const newX = view.node.position.x + delta;
|
const newX = view.node.position.x + delta;
|
||||||
|
|
||||||
// 设置朝向
|
// 🔥 使用优化的转向方法
|
||||||
if (direction === 1) {
|
this.setFacing(view, move, direction);
|
||||||
view.node.setScale(1, 1, 1); // 面向右侧
|
|
||||||
view.node.getChildByName("top").setScale(1, 1, 1); // 面向右侧
|
|
||||||
} else {
|
|
||||||
view.node.setScale(-1, 1, 1); // 面向左侧
|
|
||||||
view.node.getChildByName("top").setScale(-1, 1, 1); // 面向左侧
|
|
||||||
}
|
|
||||||
|
|
||||||
// 确保不会超过目标位置
|
// 确保不会超过目标位置
|
||||||
if (direction === 1 && newX > finalTargetX) {
|
if (direction === 1 && newX > finalTargetX) {
|
||||||
@@ -134,8 +129,7 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
|||||||
view.status_change("idle");
|
view.status_change("idle");
|
||||||
// 到达目标位置后,面向右侧(敌人方向)
|
// 到达目标位置后,面向右侧(敌人方向)
|
||||||
move.direction = 1;
|
move.direction = 1;
|
||||||
view.node.setScale(1, 1, 1); // 面向右侧
|
this.setFacing(view, move, 1); // 🔥 使用优化的转向方法
|
||||||
view.node.getChildByName("top").setScale(1, 1, 1); // 面向右侧
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
view.status_change("idle");
|
view.status_change("idle");
|
||||||
@@ -143,6 +137,24 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 🔥 优化的转向方法:只在真正需要改变朝向时才调用setScale
|
||||||
|
* 避免频繁的setScale调用导致碰撞器重新计算
|
||||||
|
*/
|
||||||
|
private setFacing(view: HeroViewComp, move: HeroMoveComp, newFacing: number) {
|
||||||
|
// 只有当朝向真正改变时才更新
|
||||||
|
if (move.currentFacing !== newFacing) {
|
||||||
|
move.currentFacing = newFacing;
|
||||||
|
view.node.setScale(newFacing, 1, 1);
|
||||||
|
|
||||||
|
// 安全获取top节点
|
||||||
|
const topNode = view.node.getChildByName("top");
|
||||||
|
if (topNode) {
|
||||||
|
topNode.setScale(newFacing, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 检查是否存在敌人 */
|
/** 检查是否存在敌人 */
|
||||||
private checkEnemiesExist(entity: ecs.Entity): boolean {
|
private checkEnemiesExist(entity: ecs.Entity): boolean {
|
||||||
const team = entity.get(HeroAttrsComp).fac;
|
const team = entity.get(HeroAttrsComp).fac;
|
||||||
|
|||||||
@@ -311,12 +311,24 @@ export class HeroViewComp extends CCComp {
|
|||||||
this.back()
|
this.back()
|
||||||
this.showDamage(damage, isCrit, SConf.DAnm); // 暴击状态由战斗系统内部处理, DAnm和EAnm共用设定数组
|
this.showDamage(damage, isCrit, SConf.DAnm); // 暴击状态由战斗系统内部处理, DAnm和EAnm共用设定数组
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isBackingUp: boolean = false; // 🔥 添加后退状态标记
|
||||||
|
|
||||||
//后退
|
//后退
|
||||||
back(){
|
back(){
|
||||||
|
// 🔥 防止重复调用后退动画
|
||||||
|
if (this.isBackingUp) return;
|
||||||
|
|
||||||
if(this.model.fac==FacSet.MON) {
|
if(this.model.fac==FacSet.MON) {
|
||||||
|
this.isBackingUp = true; // 🔥 设置后退状态
|
||||||
let tx=this.node.position.x+30
|
let tx=this.node.position.x+30
|
||||||
if(tx > 320) tx=320
|
if(tx > 320) tx=320
|
||||||
tween(this.node).to(0.1, { position:v3(tx,this.node.position.y,0)}).start()
|
tween(this.node)
|
||||||
|
.to(0.1, { position:v3(tx,this.node.position.y,0)})
|
||||||
|
.call(() => {
|
||||||
|
this.isBackingUp = false; // 🔥 动画完成后重置状态
|
||||||
|
})
|
||||||
|
.start()
|
||||||
}
|
}
|
||||||
//英雄不再后退
|
//英雄不再后退
|
||||||
// if(this.model.fac==FacSet.HERO) {
|
// if(this.model.fac==FacSet.HERO) {
|
||||||
|
|||||||
Reference in New Issue
Block a user