mirror of
https://github.com/kirikayakazuto/CocosCreator_ECS
synced 2025-01-14 06:51:55 +00:00
121 lines
5.6 KiB
TypeScript
121 lines
5.6 KiB
TypeScript
import { ComAttackable } from "../components/ComAttackable";
|
|
import { ComBeAttacked } from "../components/ComBeAttacked";
|
|
import { ComMonitor } from "../components/ComMonitor";
|
|
import { ComRoleConfig } from "../components/ComRoleConfig";
|
|
import { ComTransform } from "../components/ComTransform";
|
|
import { ECSSystem } from "../lib/ECSSystem";
|
|
import { ECSWorld, GenFillterKey } from "../lib/ECSWorld";
|
|
|
|
const FILTER_ATTACKABLE = GenFillterKey([ComAttackable]);
|
|
const FILTER_BEATTACKED = GenFillterKey([ComBeAttacked]);
|
|
export class SysAttack extends ECSSystem {
|
|
/** 连接 */
|
|
public onAdd(world: ECSWorld): void {
|
|
|
|
}
|
|
/** 断开连接 */
|
|
public onRemove(world: ECSWorld): void {
|
|
|
|
}
|
|
/** 添加实体 */
|
|
public onEntityEnter(world: ECSWorld, entity: number): void {
|
|
|
|
}
|
|
/** */
|
|
public onEntityLeave(world: ECSWorld, entity: number): void {
|
|
let filter = world.getFilter(FILTER_ATTACKABLE);
|
|
// 判断当前monitor是否
|
|
filter.entities.forEach((value: boolean, otherEntity: number) => {
|
|
let comBeAttacked = world.getComponent(otherEntity, ComBeAttacked);
|
|
if(!comBeAttacked) return ;
|
|
if(comBeAttacked.attacker == entity) comBeAttacked.attacker = -1;
|
|
});
|
|
}
|
|
/** 更新 */
|
|
public onUpdate(world: ECSWorld, dt: number): void {
|
|
let filter = world.getFilter(FILTER_ATTACKABLE);
|
|
filter.walk((entity: number) => {
|
|
let comTransSelf = world.getComponent(entity, ComTransform);
|
|
let comAttackable = world.getComponent(entity, ComAttackable);
|
|
let comRoleConfigSelf = world.getComponent(entity, ComRoleConfig);
|
|
if(!comAttackable.dirty) return ;
|
|
|
|
comAttackable.countDown -= dt;
|
|
if(comAttackable.countDown <= 0) {
|
|
comAttackable.dirty = false;
|
|
for(const entityOther of comAttackable.willHurts) {
|
|
let comBeAttacked = world.getComponent(entityOther, ComBeAttacked);
|
|
if(comBeAttacked && comBeAttacked.attacker == entity) comBeAttacked.attacker = -1;
|
|
}
|
|
comAttackable.willHurts.length = 0;
|
|
}
|
|
|
|
let limitX = comTransSelf.x + Math.sign(comTransSelf.dir.x) * comAttackable.hurtArea.x;
|
|
let minX = Math.min(comTransSelf.x, limitX);
|
|
let maxX = Math.max(comTransSelf.x, limitX);
|
|
let minY = comTransSelf.y - comAttackable.hurtArea.y;
|
|
let maxY = comTransSelf.y + comAttackable.hurtArea.y;
|
|
|
|
let _checkBeAttack = (entityOther: number) => {
|
|
if(entity == entityOther) return false;
|
|
let comRoleConfigOther = world.getComponent(entityOther, ComRoleConfig);
|
|
if(!comRoleConfigOther || comRoleConfigOther.team == comRoleConfigSelf.team) return false;
|
|
let comTransOther = world.getComponent(entityOther, ComTransform);
|
|
if(comTransOther.x < minX || comTransOther.x > maxX || Math.abs(comTransOther.y - comTransSelf.y) >= comAttackable.hurtArea.y) {
|
|
return false;
|
|
}
|
|
return true
|
|
}
|
|
|
|
comAttackable.debugInfo = {
|
|
points: [cc.v2(minX, minY), cc.v2(maxX, minY), cc.v2(maxX, maxY), cc.v2(minX, maxY)],
|
|
color: cc.Color.RED,
|
|
};
|
|
|
|
// 即将攻击未完成, 并且处于即将攻击时间段
|
|
if(!comAttackable.willHurtFrameCompleted && comAttackable.countDown <= comAttackable.willHurtFrame) {
|
|
comAttackable.willHurtFrameCompleted = true;
|
|
world.getFilter(FILTER_BEATTACKED).walk((entityOther: number) => {
|
|
if(!_checkBeAttack(entityOther)) return ;
|
|
let comBeAttackedOther = world.getComponent(entityOther, ComBeAttacked);
|
|
comBeAttackedOther.attacker = entity;
|
|
comAttackable.willHurts.push(entityOther)
|
|
|
|
return false;
|
|
})
|
|
}
|
|
|
|
if(!comAttackable.hurtFrameCompleted && comAttackable.countDown <= comAttackable.hurtFrame) {
|
|
comAttackable.hurtFrameCompleted = true;
|
|
world.getFilter(FILTER_BEATTACKED).walk((entityOther: number) => {
|
|
let comBeAttacked = world.getComponent(entityOther, ComBeAttacked);
|
|
if(comBeAttacked && comBeAttacked.attacker == entity) comBeAttacked.attacker = -1;
|
|
if(!_checkBeAttack(entityOther)) return ;
|
|
|
|
let comRoleConfigOther = world.getComponent(entityOther, ComRoleConfig);
|
|
|
|
// 扣血
|
|
if(!comRoleConfigOther || comRoleConfigOther.nowHP <= 0) return ;
|
|
comRoleConfigOther.lastHP = comRoleConfigOther.nowHP;
|
|
comRoleConfigOther.nowHP -= comAttackable.attack;
|
|
comRoleConfigOther.HPDirty = true;
|
|
|
|
// 打断对方的攻击动作
|
|
let comAttackableOther = world.getComponent(entityOther, ComAttackable);
|
|
if(!comAttackableOther || comAttackableOther.countDown <= 0) return ;
|
|
comAttackableOther.hurtFrameCompleted = true;
|
|
comAttackableOther.countDown = 0.25;
|
|
|
|
let comMonitorOther = world.getComponent(entityOther, ComMonitor);
|
|
if(comMonitorOther.others.indexOf(entity) == -1) {
|
|
comMonitorOther.others[0] = entity;
|
|
}
|
|
|
|
return false;
|
|
});
|
|
}
|
|
|
|
return false;
|
|
});
|
|
}
|
|
} |