This commit is contained in:
honmono
2022-03-21 17:27:37 +08:00
commit 91e741a895
320 changed files with 42373 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
import { ComAttackable } from "../components/ComAttackable";
import { ComBeAttacked } from "../components/ComBeAttacked";
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 {
}
/** 更新 */
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.countDown <= 0) return ;
comAttackable.countDown -= dt;
if(comAttackable.mustAttackFrame)
if(comAttackable.dirty && comAttackable.countDown <= comAttackable.hurtFrame) {
comAttackable.dirty = false;
world.getFilter(FILTER_BEATTACKED).walk((entityOther: number) => {
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;
}
comAttackable.countDown = 0.25;
return false;
});
}
return false;
});
}
}

View File

@@ -0,0 +1,10 @@
{
"ver": "1.1.0",
"uuid": "780c245c-45f2-47ae-a01a-b61dcfb3ab3e",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -0,0 +1,65 @@
import { BT } from "../../Common/BehaviorTree";
import { ComBehaviorTree } from "../components/ComBehaviorTree";
import { ECSSystem } from "../lib/ECSSystem";
import { ECSWorld, GenFillterKey } from "../lib/ECSWorld";
const FILTER_BEHAVIORTREE = GenFillterKey([ComBehaviorTree]);
const Context = new BT.ExecuteContext();
export class SysBehaviorTree extends ECSSystem {
/** 连接 */
public onAdd(world: ECSWorld): void{
Context.init(this, world);
}
/** 断开连接 */
public onRemove(world: ECSWorld): void {
}
/** 添加实体 */
public onEntityEnter(world: ECSWorld, entity: number): void {
}
/** */
public onEntityLeave(world: ECSWorld, entity: number): void {
}
/** 更新 */
public onUpdate(world: ECSWorld, dt: number): void {
Context.executor = this;
Context.dt = dt;
Context.world = world;
world.getFilter(FILTER_BEHAVIORTREE).walk((entity: number) => {
let comBehavior = world.getComponent(entity, ComBehaviorTree);
Context.set(entity, dt, comBehavior.bb);
if(comBehavior.root.state !== BT.NodeState.Executing) {
this.onEnterBTNode(comBehavior.root, Context);
}else {
this.updateBTNode(comBehavior.root, Context);
}
return false;
});
}
/** 进入节点 */
public onEnterBTNode(node: BT.NodeBase, context: BT.ExecuteContext) {
let handler = BT.NodeHandlers[node.type];
handler.onEnter(node, context);
}
/** 更新节点状态 */
public updateBTNode(node: BT.NodeBase, context: BT.ExecuteContext) {
let handler = BT.NodeHandlers[node.type];
handler.onUpdate(node, context);
}
public canExecuteBTNode(node: BT.NodeBase, context: BT.ExecuteContext) : boolean {
return true;
}
}

View File

@@ -0,0 +1,10 @@
{
"ver": "1.1.0",
"uuid": "1b6bd6b5-cb8e-46e8-8052-8ed53e75a2e5",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -0,0 +1,96 @@
import CocosHelper from "../../Common/CocosHelper";
import { ComNodeConfig } from "../components/ComNodeConfig";
import { ComCocosNode } from "../components/ComCocosNode";
import { ECSSystem } from "../lib/ECSSystem";
import { ECSWorld, GenFillterKey } from "../lib/ECSWorld";
import { ComTransform } from "../components/ComTransform";
import { EventProcess } from "../../Core/EventProcess";
import { ComRoleConfig } from "../components/ComRoleConfig";
export interface ITouchProcessor {
onTouchStart(worldPos: cc.Vec2, world: ECSWorld): void;
onTouchMove?(worldPos: cc.Vec2, world: ECSWorld): void;
onTouchEnd?(worldPos: cc.Vec2, world: ECSWorld): void;
onTouchCancel?(worldPos: cc.Vec2, world: ECSWorld): void;
}
const FILTER_COCOS_NODE = GenFillterKey([ComNodeConfig], [ComCocosNode]);
const FILTER_NODE_EVENT = GenFillterKey([ComCocosNode, ComTransform]);
export class SysCocosView extends ECSSystem implements ITouchProcessor {
onTouchStart(worldPos: cc.Vec2, world: ECSWorld): boolean {
return false;
}
onAdd(world: ECSWorld) {
}
onRemove(world: ECSWorld) {
}
onEntityEnter(world: ECSWorld, entity: number) {
}
onEntityLeave(world: ECSWorld, entity: number) {
}
onUpdate(world:ECSWorld, dt:number) {
world.getFilter(FILTER_COCOS_NODE).walk((entity: number) => {
let comNodeConfig = world.getComponent(entity, ComNodeConfig);
let comView = world.addComponent(entity, ComCocosNode);
let comRoleConfig = world.getComponent(entity, ComRoleConfig);
this._loadView(world, entity, comNodeConfig).then((node: cc.Node) => {
console.log('load view success');
});
return false;
});
world.getFilter(FILTER_NODE_EVENT).walk((entity: number) => {
let comCocosNode = world.getComponent(entity, ComCocosNode);
if(!comCocosNode.loaded) return ;
let eventProcess = comCocosNode.node.getComponent(EventProcess);
if(!eventProcess) return ;
let comTrans = world.getComponent(entity, ComTransform);
eventProcess.sync(comTrans.x, comTrans.y, comTrans.dir);
while(comCocosNode.events.length) {
let event = comCocosNode.events.shift();
eventProcess.processEvent(event);
}
return true;
});
}
private async _loadView(world: ECSWorld, entity: number, nodeConfig: ComNodeConfig) {
let prefab = await CocosHelper.loadResSync<cc.Prefab>(nodeConfig.prefabUrl, cc.Prefab);
if(!prefab) {
cc.warn(`加载失败: ${nodeConfig.prefabUrl}`);
return;
}
let comView = world.getComponent(entity, ComCocosNode);
if(comView.node) { // 销毁当前node
this.destoryView(comView.node);
}
let layers = cc.find('Canvas/Layers');
if(!layers) return ;
let node = cc.instantiate(prefab);
node.parent = layers.getChildByName(`${nodeConfig.layer}`);
comView.node = node;
comView.loaded = true;
return node;
}
private destoryView(node: cc.Node) {
node.removeFromParent();
node.destroy();
}
}

View File

@@ -0,0 +1,10 @@
{
"ver": "1.1.0",
"uuid": "e4f95950-b571-48dd-8c95-7808eef0c336",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -0,0 +1,82 @@
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_MONITOR = GenFillterKey([ComRoleConfig, ComTransform, ComMonitor]);
export class SysMonitor 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_MONITOR);
// 判断当前monitor是否
filter.entities.forEach((value: boolean, otherEntity: number) => {
let comMonitor = world.getComponent(otherEntity, ComMonitor);
if(!comMonitor) return ;
for(let i=comMonitor.others.length-1; i>=0; i--) {
if(comMonitor.others[i] == entity) {
comMonitor.others.splice(i);
}
}
});
}
/** 更新 */
public onUpdate(world: ECSWorld, dt: number): void {
let filter = world.getFilter(FILTER_MONITOR);
filter.walk((entity: number) => {
let comMonitor = world.getComponent(entity, ComMonitor);
let comTrans = world.getComponent(entity, ComTransform);
let comRoleConfig = world.getComponent(entity, ComRoleConfig);
// 判断当前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);
}
}
if(comMonitor.others.indexOf(otherEntity) == -1 && _check(comTransOther)) {
comMonitor.others.push(otherEntity);
}
});
return false;
});
}
}
// 判断一个点是否在三角形内
function isInTriangle(point: cc.Vec2, triA: cc.Vec2, triB: cc.Vec2, triC: cc.Vec2) {
let AB = triB.sub(triA), AC = triC.sub(triA), BC = triC.sub(triB), AD = point.sub(triA), BD = point.sub(triB);
//@ts-ignore
return (AB.cross(AC) >= 0 ^ AB.cross(AD) < 0) && (AB.cross(AC) >= 0 ^ AC.cross(AD) >= 0) && (BC.cross(AB) > 0 ^ BC.cross(BD) >= 0);
}

View File

@@ -0,0 +1,10 @@
{
"ver": "1.1.0",
"uuid": "0b207deb-ff30-4fbe-aca7-2f77f299569d",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -0,0 +1,70 @@
import { ComCocosNode as ComCocosNode } from "../components/ComCocosNode";
import { ComMovable } from "../components/ComMovable";
import { ComTransform } from "../components/ComTransform";
import { ECSSystem } from "../lib/ECSSystem";
import { ECSWorld, GenFillterKey as GenFilterKey } from "../lib/ECSWorld";
const FILTER_MOVE = GenFilterKey([ComMovable, ComTransform, ComCocosNode]);
export class SysMovable 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 {
}
/** 更新 */
public onUpdate(world: ECSWorld, dt:number): void {
world.getFilter(FILTER_MOVE).walk((entity: number) => {
let comMovable = world.getComponent(entity, ComMovable);
let comTrans = world.getComponent(entity, ComTransform);
if(comMovable.speed <= 0 || comMovable.pointIdx >= comMovable.points.length) {
return ;
}
if(!comMovable.running) {
comMovable.running = true;
}
let moveLen = comMovable.speed * dt;
while(moveLen > 0 && comMovable.pointIdx < comMovable.points.length) {
let nextPoint = comMovable.points[comMovable.pointIdx];
let offsetX = nextPoint.x - comTrans.x;
let offsetY = nextPoint.y - comTrans.y;
let offsetLen = Math.sqrt(offsetX * offsetX + offsetY * offsetY);
if(offsetLen <= moveLen) {
moveLen -= offsetLen;
comTrans.x = nextPoint.x;
comTrans.y = nextPoint.y;
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;
moveLen = -1;
}
if(comMovable.pointIdx >= comMovable.points.length) {
comMovable.speed = 0;
comMovable.speedDirty = true;
}
return false;
});
}
}

View File

@@ -0,0 +1,10 @@
{
"ver": "1.1.0",
"uuid": "6f024564-9b8c-47ad-95eb-eca4afd96720",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}

View File

@@ -0,0 +1,69 @@
import { EventDeath, EventHPChange, EventHurt, EventRun, EventStand } from "../../Struct/NodeEvent";
import { ComBehaviorTree } from "../components/ComBehaviorTree";
import { ComCocosNode } from "../components/ComCocosNode";
import { ComMonitor } from "../components/ComMonitor";
import { ComMovable } from "../components/ComMovable";
import { ComNodeConfig } from "../components/ComNodeConfig";
import { ComRoleConfig } from "../components/ComRoleConfig";
import { ECSSystem } from "../lib/ECSSystem";
import { ECSWorld, GenFillterKey } from "../lib/ECSWorld";
const FILTER_ROLE_NODE = GenFillterKey([ComCocosNode, ComRoleConfig]);
export class SysRoleState 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 {
}
/** 更新 */
public onUpdate(world: ECSWorld, dt: number): void {
world.getFilter(FILTER_ROLE_NODE).walk((entity: number) => {
let comCocosNode = world.getComponent(entity, ComCocosNode);
if(!comCocosNode.loaded) return ;
let comRoleConfig = world.getComponent(entity, ComRoleConfig);
let comMovable = world.getComponent(entity, ComMovable);
if(comMovable && comMovable.speedDirty) {
comMovable.speedDirty = false;
if(comMovable.speed > 0) {
comCocosNode.events.push(new EventRun());
}else {
comCocosNode.events.push(new EventStand());
}
}
if(comRoleConfig && comRoleConfig.HPDirty) {
comCocosNode.events.push(new EventHPChange(comRoleConfig.maxHP, comRoleConfig.lastHP, comRoleConfig.nowHP));
if(comRoleConfig.lastHP > comRoleConfig.nowHP) {
comCocosNode.events.push(new EventHurt());
}
if(comRoleConfig.nowHP <= 0) {
comCocosNode.events.push(new EventDeath(() => {
world.removeComponent(entity, ComNodeConfig);
world.removeComponent(entity, ComCocosNode);
world.removeEntity(entity);
comCocosNode.node.destroy();
}));
world.removeComponent(entity, ComBehaviorTree);
world.removeComponent(entity, ComMonitor);
world.removeComponent(entity, ComMovable);
world.removeComponent(entity, ComRoleConfig);
}
comRoleConfig.HPDirty = false;
}
return false;
});
}
}

View File

@@ -0,0 +1,10 @@
{
"ver": "1.1.0",
"uuid": "b679be6f-54ac-4790-99ff-41e3993bf130",
"importer": "typescript",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}