This commit is contained in:
honmono
2022-03-22 15:35:41 +08:00
parent 91e741a895
commit c7d30bc03b
16 changed files with 531 additions and 125 deletions

View File

@@ -1,5 +1,6 @@
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";
@@ -31,36 +32,79 @@ export class SysAttack extends ECSSystem {
let comTransSelf = world.getComponent(entity, ComTransform);
let comAttackable = world.getComponent(entity, ComAttackable);
let comRoleConfigSelf = world.getComponent(entity, ComRoleConfig);
if(comAttackable.countDown <= 0) return ;
comAttackable.countDown -= dt;
if(!comAttackable.dirty) return ;
if(comAttackable.mustAttackFrame)
if(comAttackable.dirty && comAttackable.countDown <= comAttackable.hurtFrame) {
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);
let comTransOther = world.getComponent(entityOther, ComTransform);
if(!comRoleConfigOther || comRoleConfigOther.team == comRoleConfigSelf.team) return ;
let xDiff = comTransOther.x - comTransSelf.x;
if(xDiff * Math.sign(xDiff) >= comAttackable.hurtArea.x || Math.abs(comTransOther.y - comTransSelf.y) >= comAttackable.hurtArea.y) {
return ;
}
// 扣血
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 ;
if(comAttackableOther.countDown >= comAttackableOther.mustAttackFrame) {
comAttackableOther.dirty = false;
comAttackableOther.hurtFrameCompleted = true;
comAttackableOther.countDown = 0.25;
let comMonitorOther = world.getComponent(entityOther, ComMonitor);
if(comMonitorOther.others.indexOf(entity) == -1) {
comMonitorOther.others[0] = entity;
}
comAttackable.countDown = 0.25;
return false;
});
}

View File

@@ -41,27 +41,31 @@ export class SysMonitor extends ECSSystem {
let comTrans = world.getComponent(entity, ComTransform);
let comRoleConfig = world.getComponent(entity, ComRoleConfig);
let a = cc.v2(comTrans.x, comTrans.y);
let centerPoint = a.add(comTrans.dir.mul(comMonitor.lookLen));
let b = centerPoint.add(cc.v2(comTrans.dir.y, -comTrans.dir.x).mul(comMonitor.lookWidth));
let c = centerPoint.add(cc.v2(-comTrans.dir.y, comTrans.dir.x).mul(comMonitor.lookWidth));
let d = centerPoint.add(comTrans.dir.mul(comMonitor.outLen));
comMonitor.debugInfo = {
points: [a, b, d, c],
color: cc.Color.BLUE,
};
// 判断当前monitor是否
filter.entities.forEach((value: boolean, otherEntity: number) => {
let comTransOther = world.getComponent(otherEntity, ComTransform);
let comRoleConfigOther = world.getComponent(otherEntity, ComRoleConfig);
if(entity == otherEntity || !comRoleConfigOther || comRoleConfigOther.team == comRoleConfig.team) return ;
let a = cc.v2(comTrans.x, comTrans.y);
let centerPoint = a.add(comTrans.dir.mul(comMonitor.lookLen));
let b = centerPoint.add(cc.v2(comTrans.dir.y, -comTrans.dir.x).mul(comMonitor.lookSize));
let c = centerPoint.add(cc.v2(-comTrans.dir.y, comTrans.dir.x).mul(comMonitor.lookSize));
let _check = (com: ComTransform) => {
return (a.sub(cc.v2(com.x, com.y)).len() < comMonitor.aroundLen || isInTriangle(cc.v2(com.x, com.y), a, b, c))
}
for(let i=comMonitor.others.length-1; i>=0; i--) {
const com = world.getComponent(comMonitor.others[i], ComTransform);
if(!com || !_check(com)) {
comMonitor.others.splice(i, 1);
}
return (a.sub(cc.v2(com.x, com.y)).len() < comMonitor.aroundLen || isInTriangle(cc.v2(com.x, com.y), a, b, c) || isInTriangle(cc.v2(com.x, com.y), b, c, d))
}
// for(let i=comMonitor.others.length-1; i>=0; i--) {
// const com = world.getComponent(comMonitor.others[i], ComTransform);
// if(!com || !_check(com)) {
// comMonitor.others.splice(i, 1);
// }
// }
if(comMonitor.others.indexOf(otherEntity) == -1 && _check(comTransOther)) {
comMonitor.others.push(otherEntity);

View File

@@ -51,10 +51,12 @@ export class SysMovable extends ECSSystem {
comMovable.pointIdx ++;
continue;
}
comTrans.dir.x = offsetX / offsetLen;
comTrans.dir.y = offsetY / offsetLen;
comTrans.x += moveLen * comTrans.dir.x;
comTrans.y += moveLen * comTrans.dir.y;
if(!comMovable.keepDir) {
comTrans.dir.x = offsetX / offsetLen || comTrans.dir.x;
comTrans.dir.y = offsetY / offsetLen;
}
comTrans.x += moveLen * offsetX / offsetLen;
comTrans.y += moveLen * offsetY / offsetLen;
moveLen = -1;
}

View File

@@ -1,4 +1,5 @@
import { EventDeath, EventHPChange, EventHurt, EventRun, EventStand } from "../../Struct/NodeEvent";
import { EventDeath, EventGraphicsDraw, EventHPChange, EventHurt, EventRun, EventStand } from "../../Struct/NodeEvent";
import { ComAttackable } from "../components/ComAttackable";
import { ComBehaviorTree } from "../components/ComBehaviorTree";
import { ComCocosNode } from "../components/ComCocosNode";
import { ComMonitor } from "../components/ComMonitor";
@@ -33,6 +34,20 @@ export class SysRoleState extends ECSSystem {
if(!comCocosNode.loaded) return ;
let comRoleConfig = world.getComponent(entity, ComRoleConfig);
let comMovable = world.getComponent(entity, ComMovable);
let comMonitor = world.getComponent(entity, ComMonitor);
let comAttackable = world.getComponent(entity, ComAttackable);
comCocosNode.events.push(new EventGraphicsDraw([]));
if(comMonitor && comMonitor.debugInfo) {
comCocosNode.events.push(new EventGraphicsDraw(comMonitor.debugInfo.points, comMonitor.debugInfo.color));
}
if(comAttackable && comAttackable.debugInfo) {
comCocosNode.events.push(new EventGraphicsDraw(comAttackable.debugInfo.points, comAttackable.debugInfo.color));
}
if(comMovable && comMovable.speedDirty) {
comMovable.speedDirty = false;