feat: 为英雄和怪物添加下落入场动画

- 在 MissionHeroComp 和 MissionMonComp 中定义下落高度常量
- 修改英雄和怪物的加载方法,接受目标落地高度参数
- 使用 Tween 实现平滑下落动画,下落距离越大持续时间越长
- 下落期间禁用移动和碰撞器,落地后恢复
- 为怪物添加随机下落高度偏移,减轻重叠感
This commit is contained in:
panw
2026-03-19 09:11:11 +08:00
parent a20e5db00b
commit 1522e93585
4 changed files with 51 additions and 20 deletions

View File

@@ -1,4 +1,4 @@
import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas, BoxCollider2D} from "cc";
import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas, BoxCollider2D, tween, Tween} from "cc";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { smc } from "../common/SingletonModuleComp";
@@ -39,7 +39,7 @@ export class Hero extends ecs.Entity {
/** 加载角色 */
load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001) {
load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001, dropToY:number = pos.y) {
scale = 1
// 查找空闲英雄槽位
let size=1
@@ -95,7 +95,24 @@ export class Hero extends ecs.Entity {
const move = this.get(MoveComp);
move.direction = 1; // 向右移动
move.targetX = resolveFormationTargetX(model.fac, model.type);
move.baseY = pos.y;
move.baseY = dropToY;
move.moving = false;
const dropDistance = Math.abs(pos.y - dropToY);
const dropDuration = Math.max(0.18, Math.min(0.38, dropDistance / 1200));
Tween.stopAllByTarget(node);
tween(node)
.to(dropDuration, { position: v3(pos.x, dropToY, 0) })
.call(() => {
if (!node || !node.isValid) return;
node.setPosition(pos.x, dropToY, 0);
move.moving = true;
if (collider) {
collider.enabled = true;
collider.group = BoxSet.HERO;
collider.apply();
}
})
.start();
smc.vmdata.mission_data.hero_num++
}

View File

@@ -1,4 +1,4 @@
import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas, BoxCollider2D, NodePool} from "cc";
import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas, BoxCollider2D, NodePool, tween, Tween} from "cc";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { smc } from "../common/SingletonModuleComp";
@@ -103,7 +103,7 @@ export class Monster extends ecs.Entity {
}
/** 加载角色 */
load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001, is_boss:boolean=false) {
load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001, is_boss:boolean=false, dropToY:number = pos.y) {
scale=-1
let size=1
var scene = smc.map.MapView.scene;
@@ -120,15 +120,7 @@ export class Monster extends ecs.Entity {
var view = node.getComponent(HeroViewComp)!;
const collider = node.getComponent(BoxCollider2D);
if (collider) {
// 先禁用,下一帧启用,确保物理系统能正确注册新激活的节点
collider.enabled = false;
view.scheduleOnce(() => {
if (node && node.isValid) {
collider.enabled = true;
collider.group = BoxSet.MONSTER; // 确保碰撞组正确
collider.apply(); // 强制应用更改(如果需要)
}
}, 0); // 0延迟等于下一帧执行
collider.enabled = false;
}
node.setScale(size*node.scale.x,size*node.scale.y);
@@ -170,7 +162,24 @@ export class Monster extends ecs.Entity {
move.reset();
move.direction = -1; // 向左移动
move.targetX = Math.max(-320, Math.min(320, pos.x));
move.baseY = pos.y;
move.baseY = dropToY;
move.moving = false;
const dropDistance = Math.abs(pos.y - dropToY);
const dropDuration = Math.max(0.18, Math.min(0.38, dropDistance / 1200));
Tween.stopAllByTarget(node);
tween(node)
.to(dropDuration, { position: v3(pos.x, dropToY, 0) })
.call(() => {
if (!node || !node.isValid) return;
node.setPosition(pos.x, dropToY, 0);
move.moving = true;
if (collider) {
collider.enabled = true;
collider.group = BoxSet.MONSTER;
collider.apply();
}
})
.start();
smc.vmdata.mission_data.mon_num++
}