去掉碰撞系统

This commit is contained in:
2025-02-02 14:48:06 +08:00
parent 6ea3e9504d
commit e571ae2caf
19 changed files with 857 additions and 66 deletions

View File

@@ -7,6 +7,7 @@ import { UIConfigData } from './game/common/config/GameUIConfig';
import { smc } from './game/common/SingletonModuleComp';
import { Initialize } from './game/initialize/Initialize';
import { EcsPositionSystem } from './game/common/ecs/position/EcsPositionSystem';
import { EcsSkillSystem } from './game/skill/EcsSkillSystem';
const { ccclass, property } = _decorator;
@@ -30,9 +31,10 @@ export class Main extends Root {
}
protected async initEcsSystem() {
oops.ecs.add(new EcsPositionSystem())
// oops.ecs.add(new EcsAccountSystem());
oops.ecs.add(new EcsPositionSystem());
oops.ecs.add(new EcsSkillSystem());
// oops.ecs.add(new EcsRoleSystem());
// oops.ecs.add(new EcsInitializeSystem());
}
}

View File

@@ -117,5 +117,20 @@ export const SkillSet = {
6031:{uuid:6031,path:"6031",type:1,tg:0,fname:"buff_do",flash:true,with:false,debuff:0,depb:0,debtime:0,derate:0,in:2,count:1,def:20,apup:0,ap:70,mhp:0,hp:70,cd:1,shield:0,speed:120,sonsk:0,hero:5211,name:"召唤仆从",sp_name:"zhaohuan",info:"召唤一个与施法者等级相同的骷髅战士为我方而战"},
6032:{uuid:6032,path:"6032",type:1,tg:0,fname:"",flash:false,with:false,debuff:0,depb:0,debtime:0,derate:0,in:2,count:1,def:0,apup:0,ap:100,mhp:0,hp:5,cd:1,shield:0,speed:120,sonsk:0,hero:0,name:"自愈",sp_name:"heath_small",info:"主动:自己回复自身5%最大生命值的生命"},
6033:{uuid:6033,path:"6033",type:1,tg:3,fname:"",flash:false,with:false,debuff:4,depb:100,debtime:1,derate:20,in:1,count:1,def:0,apup:0,ap:500,mhp:0,hp:0,cd:1,shield:0,speed:500,sonsk:6035,hero:0,name:"爆锤",sp_name:"cuida",info:"捶爆前方目标造成300%攻击的伤害震慑敌人本局内全部敌方降低对方10%攻击力"},
6034:{uuid:6034,path:"6034",type:1,tg:3,fname:"",flash:false,with:false,debuff:4,depb:100,debtime:1,derate:20,in:1,count:1,def:0,apup:0,ap:80,mhp:0,hp:0,cd:1,shield:0,speed:350,sonsk:0,hero:0,name:"暴风箭",sp_name:"bingyu",info:"射出能量暴风箭攻击最前方范围敌人,每波造成80%攻击的伤害"}
6034:{uuid:6034,path:"6034",type:1,tg:3,fname:"",flash:false,with:false,debuff:4,depb:100,debtime:1,derate:20,in:1,count:1,def:0,apup:0,ap:80,mhp:0,hp:0,cd:1,shield:0,speed:350,sonsk:0,hero:0,name:"暴风箭",sp_name:"bingyu",info:"射出能量暴风箭攻击最前方范围敌人,每波造成80%攻击的伤害"},
7001: {
prefab: "arrow", // 预制体路径
range: 500, // 攻击距离
width: 30, // 攻击宽度
penetrate: 3, // 最大穿透数
speed: 800, // 飞行速度(像素/秒)
hitInterval: 0.1 // 伤害间隔(秒)
},
8001: {
prefab: "fireball",
speed: 600,
range: 800,
penetrate: 2,
collisionRadius: 50 // 碰撞检测半径
}
};

View File

@@ -0,0 +1,17 @@
import { ecs } from "../../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
@ecs.register('BattleMove')
export class BattleMoveComp extends ecs.Comp {
/** 移动方向1向右-1向左 */
direction: number = 1;
/** 目标x坐标 */
targetX: number = 0;
/** 是否处于移动状态 */
moving: boolean = true;
reset() {
this.direction = 1;
this.targetX = 0;
this.moving = true;
}
}

View File

@@ -0,0 +1,51 @@
import { HeroViewComp } from "../../../hero/HeroViewComp";
import { BattleMoveComp } from "./BattleMoveComp";
import { ecs } from "../../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
@ecs.register('BattleMoveSystem')
export class BattleMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
filter(): ecs.IMatcher {
return ecs.allOf(BattleMoveComp, HeroViewComp);
}
update(e: ecs.Entity) {
const move = e.get(BattleMoveComp);
const view = e.get(HeroViewComp);
if (!move.moving) return;
// 检测攻击范围内是否有敌人
const hasEnemy = this.checkEnemiesInRange(e, view.dis);
if (!hasEnemy) {
// 计算移动量
const delta = view.speed * this.dt * move.direction;
const newX = view.node.position.x + delta;
// 限制移动范围
if (this.validatePosition(newX, move)) {
view.node.setPosition(newX, view.node.position.y, 0);
}
}
}
/** 验证目标位置有效性 */
private validatePosition(newX: number, move: BattleMoveComp): boolean {
// 我方不能超过右边界,敌方不能超过左边界
return move.direction === 1 ?
newX <= move.targetX :
newX >= move.targetX;
}
/** 检测攻击范围内敌人 */
private checkEnemiesInRange(entity: ecs.Entity, range: number): boolean {
const currentPos = entity.get(HeroViewComp).node.position;
const team = entity.get(HeroViewComp).fac;
return ecs.query(ecs.allOf(HeroViewComp)).some(e => {
const view = e.get(HeroViewComp);
return view.fac !== team &&
Math.abs(currentPos.x - view.node.position.x) <= range;
});
}
}

View File

@@ -1,36 +1,33 @@
import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas} from "cc";
import { UICallbacks } from "../../../../extensions/oops-plugin-framework/assets/core/gui/layer/Defines";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { UIID } from "../common/config/GameUIConfig";
import { smc } from "../common/SingletonModuleComp";
import { HeroModelComp } from "./HeroModelComp";
import { HeroSpine } from "./HeroSpine";
import { HeroViewComp } from "./HeroViewComp";
import { BoxSet } from "../common/config/BoxSet";
import { RandomManager } from "../../../../extensions/oops-plugin-framework/assets/core/common/random/RandomManager";
import { HeroInfo } from "../common/config/heroSet";
import { MoveToComp } from "../common/ecs/position/MoveTo";
import { Talents } from "../common/config/TalentSet";
import { MonModelComp } from "./MonModelComp";
import { SkillsComp } from "../skill/SkillSystem";
import { BattleMoveComp } from "../common/ecs/position/BattleMoveComp";
/** 角色实体 */
@ecs.register(`Hero`)
export class Hero extends ecs.Entity {
// 数据层
HeroModel!: HeroModelComp;
// 视图层
HeroView!: HeroViewComp;
HeroView!: HeroViewComp;
Skills!: SkillsComp;
BattleMove!: BattleMoveComp;
protected init() {
this.addComponents<ecs.Comp>(
SkillsComp,
BattleMoveComp
);
}
destroy(): void {
this.remove(HeroViewComp);
this.remove(MoveToComp);
super.destroy();
}
@@ -42,18 +39,14 @@ export class Hero extends ecs.Entity {
var path = "game/heros/"+HeroInfo[uuid].path;
var prefab: Prefab = oops.res.get(path, Prefab)!;
var node = instantiate(prefab);
var scene = smc.map.MapView.scene;
node.parent = scene.entityLayer!.node!
node.setPosition(pos)
this.hero_init(uuid,node,scale,box_group,is_call,lv)
oops.message.dispatchEvent("hero_load",this)
}
hero_init(uuid:number=1001,node:Node,scale:number=1,box_group=BoxSet.HERO,is_call:boolean=false,lv:number=1){
var hv = node.getComponent(HeroViewComp)!;
// console.log("hero_init",buff)
let hero= HeroInfo[uuid] // 共用英雄数据
let role =smc.heros[uuid]
if(is_call){
@@ -61,6 +54,7 @@ export class Hero extends ecs.Entity {
}
let talents=Talents;
hv.scale = scale;
hv.fac = 0;
hv.box_group = box_group;
hv.hero_uuid= uuid;
hv.hero_name= hero.name;
@@ -74,13 +68,11 @@ export class Hero extends ecs.Entity {
hv.cpw=hero.cpw;
hv.dpw=hero.dpw;
hv.dopw=hero.dopw;
hv.lv = role.lv;
hv.type = hero.type;
let slv= Math.floor(( hv.lv) / 5);
let sklv=slv
if(sklv >= 5) sklv=5;
hv.sk1 = hero.sk1[sklv];
hv.sk2 = hero.sk2[sklv];
hv.sk3 = hero.sk3[sklv];
@@ -104,27 +96,17 @@ export class Hero extends ecs.Entity {
hv.cexp=hero.cexp
hv.doexp=hero.doexp
hv.dexp=hero.dexp;
this.add(hv);
// 初始化多个技能组件
const skills = this.get(SkillsComp);
// 初始化移动参数
const move = this.get(BattleMoveComp);
move.direction = 1; // 向右移动
move.targetX = 800; // 右边界
console.log("hero_init",skills,move);
}
set_ratio(uuid:number){
let ratio=1;
switch (HeroInfo[uuid].level) {
case 2:
ratio=1.05
break;
case 3:
ratio=1.1
break;
case 4:
ratio=1.15
break;
case 5:
ratio=1.2
break;
default:
ratio=1
}
return ratio;
}
}

View File

@@ -5,19 +5,8 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
*/
@ecs.register('HeroModel')
export class HeroModelComp extends ecs.Comp {
/** 角色编号 */
id: number = -1;
/** 角色名 */
name: string = "mon";
/** speed */
// speed: number = 0;
/** 动画名资源 */
anim: string = "mon";
reset() {
this.id = -1;
// this.speed = 0;
this.name = "";
}
}

View File

@@ -1,9 +1,3 @@
/*
* @Author: dgflash
* @Date: 2021-11-18 17:42:59
* @LastEditors: dgflash
* @LastEditTime: 2022-08-17 12:36:18
*/
import { Vec3, _decorator , v3,Collider2D,Contact2DType,Label,RigidBody2D ,Node,Prefab,instantiate,ProgressBar, Component, Material, Sprite, math, clamp, Game, tween} from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
@@ -42,11 +36,12 @@ export class HeroViewComp extends CCComp {
slv:number =1;
scale: number = 1; /** 角色阵营 1hero -1 :mon */
type: number = 0; /**角色类型 0近战 1 远程 2 辅助 */
fac:number=0; //阵营 0hero 1monster
box_group:number = BoxSet.HERO;
atk_range:number = 150;
is_dead:boolean = false; //是否摧毁
is_stop:boolean = false;
is_atking:boolean = false;

View File

@@ -1,4 +1,3 @@
/*
* @Author: dgflash
* @Date: 2021-11-18 17:47:56
@@ -20,6 +19,7 @@ import { HeroInfo } from "../common/config/heroSet";
import { MoveToComp } from "../common/ecs/position/MoveTo";
import { Talents } from "../common/config/TalentSet";
import { MonModelComp } from "./MonModelComp";
import { BattleMoveComp } from "../common/ecs/position/BattleMoveComp";
/** 角色实体 */
@ecs.register(`Monster`)
export class Monster extends ecs.Entity {
@@ -45,7 +45,7 @@ export class Monster extends ecs.Entity {
scale=-1
let box_group=BoxSet.MONSTER
console.log("mon load",uuid)
this.addComponents<ecs.Comp>( MonModelComp);
this.addComponents<ecs.Comp>( MonModelComp, BattleMoveComp);
var path = "game/heros/"+HeroInfo[uuid].path;
var prefab: Prefab = oops.res.get(path, Prefab)!;
var node = instantiate(prefab);
@@ -55,6 +55,11 @@ export class Monster extends ecs.Entity {
node.setPosition(pos)
this.hero_init(uuid,node,scale,box_group,is_boss,is_call,lv)
oops.message.dispatchEvent("monster_load",this)
// 初始化移动参数
const move = this.get(BattleMoveComp);
move.direction = -1; // 向左移动
move.targetX = -800; // 左边界
}
hero_init(uuid:number=1001,node:Node,scale:number=1,box_group=BoxSet.HERO,is_boss:boolean=false,is_call:boolean=false,lv:number=1) {
@@ -64,6 +69,7 @@ export class Monster extends ecs.Entity {
let talent= smc.vmdata.talent //角色英雄数据
let talents=Talents;
hv.scale = scale;
hv.fac = 1;
hv.is_boss = is_boss;
hv.box_group = box_group;
hv.hero_uuid= uuid;

View File

@@ -0,0 +1,9 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "8003b099-fab7-454f-b142-3f767dc597ee",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,5 +1,5 @@
{
"ver": "1.1.0",
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "a80a879f-d214-454c-a574-18f080ae0d91",

View File

@@ -0,0 +1,11 @@
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { SkillSystem } from "./SkillSystem";
import { SkillAnimationSystem } from "./SkillAnimation";
export class EcsSkillSystem extends ecs.System {
constructor() {
super();
this.add(new SkillSystem());
this.add(new SkillAnimationSystem());
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "ea1f8dae-6593-46bf-b20b-a301b495a434",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,79 @@
import { Vec3 } from "cc";
import { ecs } from "db://oops-framework/libs/ecs/ECS";
import { HeroViewComp } from "../hero/HeroViewComp";
// 投射物组件
@ecs.register('Projectile')
export class ProjectileComp extends ecs.Comp {
speed: number = 500; // 飞行速度
direction: Vec3 = Vec3.RIGHT;// 飞行方向
maxDistance: number = 1000; // 最大射程
traveled: number = 0; // 已飞行距离
penetrate: number = 3; // 穿透次数
targets = new Set<ecs.Entity>(); // 已命中目标
reset() {
this.speed = 500;
this.direction.set(Vec3.RIGHT);
this.maxDistance = 1000;
this.traveled = 0;
this.penetrate = 3;
this.targets.clear();
}
}
// 投射物系统
@ecs.register('ProjectileSystem')
export class ProjectileSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
filter(): ecs.IMatcher {
return ecs.allOf(ProjectileComp, HeroViewComp);
}
update(e: ecs.Entity): void {
const proj = e.get(ProjectileComp);
const view = e.get(HeroViewComp);
// 移动计算
const delta = proj.direction.multiplyScalar(proj.speed * this.dt);
view.node.position = view.node.position.add(delta);
proj.traveled += delta.length();
// 碰撞检测使用ECS组件检测
this.checkCollision(e);
// 超出射程销毁
if (proj.traveled >= proj.maxDistance) {
e.destroy();
}
}
private checkCollision(e: ecs.Entity) {
const proj = e.get(ProjectileComp);
const view = e.get(HeroViewComp);
// 获取范围内所有敌人
// const enemies = ecs.getEntities(HeroViewComp).filter(entity => {
// const enemyView = entity.get(HeroViewComp);
// return enemyView.boxGroup !== view.boxGroup &&
// Vec3.distance(view.node.position, enemyView.node.position) <= 50; // 碰撞半径
// });
// enemies.forEach(enemy => {
// if (!proj.targets.has(enemy)) {
// this.applyDamage(e, enemy);
// proj.targets.add(enemy);
// proj.penetrate--;
// }
// });
if (proj.penetrate <= 0) {
e.destroy();
}
}
private applyDamage(projectile: ecs.Entity, target: ecs.Entity) {
const projView = projectile.get(HeroViewComp);
const targetView = target.get(HeroViewComp);
// targetView.takeDamage(projView.attack);
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "f563271b-ee28-4cc0-86ec-6947e9fe454e",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,55 @@
import { ecs ,} from "db://oops-framework/libs/ecs/ECS";
import { HeroViewComp } from "../hero/HeroViewComp";
import { SkillsComp } from "./SkillSystem";
import { SkillSet } from "../common/config/SkillSet";
import { Node } from "cc";
// 动画组件
@ecs.register('SkillAnimation')
export class SkillAnimationComp extends ecs.Comp {
prefab: Node | null = null; // 预制体实例
damageTriggerTime = 0.3; // 伤害触发时间(秒)
elapsed = 0; // 已播放时间
reset() {
this.prefab?.destroy();
this.prefab = null;
this.damageTriggerTime = 0.3;
this.elapsed = 0;
}
}
// 动画系统
@ecs.register('SkillAnimationSystem')
export class SkillAnimationSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
filter(): ecs.IMatcher {
return ecs.allOf(SkillAnimationComp, HeroViewComp);
}
update(e: ecs.Entity): void {
const anim = e.get(SkillAnimationComp);
anim.elapsed += this.dt;
// 伤害触发检测
// if (!anim.hitted && anim.elapsed >= anim.hitTime) {
// this.applyDamage(e);
// anim.hitted = true;
// }
// 更新动画状态
// if (anim.elapsed >= anim.duration) {
// e.remove(SkillAnimationComp);
// }
}
private applyDamage(e: ecs.Entity) {
const skill = e.get(SkillsComp);
const view = e.get(HeroViewComp);
// 添加伤害标记组件
}
// 在角色组件中实现目标查找
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "8c885682-d6d1-4bca-a06b-edb7e1389c08",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,187 @@
import { Node, Vec3 } from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { HeroViewComp } from "../hero/HeroViewComp";
import { SkillSet } from "../common/config/SkillSet";
import { SkillAnimationComp } from "./SkillAnimation";
import { ProjectileComp } from "./ProjectileComp";
/** 技能触发组件 */
@ecs.register('HerosSkills')
export class SkillsComp extends ecs.Comp {
/** 技能ID */
skillId: number = 0;
/** 目标位置/实体 */
target: Vec3 | Node | null = null;
/** 当前冷却时间 */
currentCooldown: number = 0;
reset() {
this.skillId = 0;
this.target = null;
this.currentCooldown = 0;
}
}
/** 技能系统 */
@ecs.register('SkillSystem')
export class SkillSystem extends ecs.ComblockSystem<ecs.Entity> implements ecs.ISystemUpdate {
filter(): ecs.IMatcher {
return ecs.allOf(SkillsComp, HeroViewComp);
}
update(e: ecs.Entity) {
let skill = e.get(SkillsComp);
let view = e.get(HeroViewComp);
if (this.canCastSkill(skill, view)) {
this.castSkill(e, skill);
}
}
private canCastSkill(skill: SkillsComp, view: HeroViewComp): boolean {
return skill.currentCooldown <= 0 &&
view.pw >= view.pwm;
}
private castSkill(entity: ecs.Entity, skill: SkillsComp) {
const skillData = SkillSet[skill.skillId];
// // 创建飞弹实体
// const projectile = ecs.createEntity();
// const projView = projectile.add(HeroViewComp);
// projView.node = instantiate(skillData.prefab);
// projView.node.setParent(entity.get(HeroViewComp).node.parent);
// projView.node.setPosition(entity.get(HeroViewComp).node.position);
// // 添加投射物组件
// projectile.add(ProjectileComp, {
// speed: skillData.speed,
// direction: entity.get(HeroViewComp).node.scale.x > 0 ? Vec3.RIGHT : Vec3.LEFT,
// maxDistance: skillData.range,
// penetrate: skillData.penetrate
// });
// 应用冷却时间
skill.currentCooldown = skillData.cooldown;
// 根据技能类型处理
switch(skillData.type) {
case 'damage':
this.handleDamage(entity, skillData);
break;
case 'heal':
this.handleHeal(entity, skillData);
break;
case 'projectile':
this.castProjectileSkill(entity, skillData);
break;
}
// 播放动画(示例)
// entity.get(HeroViewComp).playAnimation(skillData.anim);
// 触发完成回调
entity.remove(SkillsComp);
}
private handleDamage(entity: ecs.Entity, data: any) {
const view = entity.get(HeroViewComp);
// 实现伤害逻辑...
}
private handleHeal(entity: ecs.Entity, data: any) {
const view = entity.get(HeroViewComp);
// 实现治疗逻辑...
}
private castProjectileSkill(entity: ecs.Entity, skillData: any) {
const view = entity.get(HeroViewComp);
// 创建飞弹实体
}
private exit(e: ecs.Entity) {
e.remove(SkillsComp);
}
}
// 动画系统
@ecs.register('SkillAnimationSystem')
export class SkillAnimationSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
filter(): ecs.IMatcher {
return ecs.allOf(SkillAnimationComp);
}
update(e: ecs.Entity): void {
const anim = e.get(SkillAnimationComp);
anim.elapsed += this.dt;
// 触发伤害检测
if (anim.elapsed >= anim.damageTriggerTime) {
e.add(DamageLineComp); // 添加伤害区域组件
e.remove(SkillAnimationComp);
}
}
}
// 直线型伤害区域组件
@ecs.register('DamageLine')
export class DamageLineComp extends ecs.Comp {
startPos: Vec3 = new Vec3();
direction: Vec3 = Vec3.RIGHT;
length: number = 300;
width: number = 50;
reset() {
this.startPos.set();
this.direction.set(Vec3.RIGHT);
this.length = 300;
this.width = 50;
}
}
// 直线伤害系统
@ecs.register('DamageLineSystem')
export class DamageLineSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
filter(): ecs.IMatcher {
return ecs.allOf(DamageLineComp, HeroViewComp);
}
update(e: ecs.Entity): void {
const line = e.get(DamageLineComp);
const caster = e.get(HeroViewComp);
// 根据角色朝向调整方向
line.direction = caster.node.scale.x > 0 ? Vec3.RIGHT : new Vec3(-1, 0, 0);
// 获取直线区域内的目标
const targets = this.getTargetsInLine(
caster.node.worldPosition,
line.direction,
line.length,
line.width,
caster.box_group
);
// 应用伤害
targets.forEach(target => {
});
e.remove(DamageLineComp);
}
private getTargetsInLine(origin: Vec3, dir: Vec3, length: number, width: number, team: number): ecs.Entity[] {
return [];
}
private isInLine(origin: Vec3, dir: Vec3, target: Vec3, length: number, width: number): boolean {
return false; // 临时返回值保持类型安全
// const toTarget = target.subtract(origin);
// const projection = Vec3.project(toTarget, dir);
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.23",
"importer": "typescript",
"imported": true,
"uuid": "c927f5c9-45cb-4400-8734-c706e615e4a4",
"files": [],
"subMetas": {},
"userData": {}
}