diff --git a/README.md b/README.md index 576fa74..ec54507 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 在Cocos中使用ECS + BehaviorTree 实现格斗AI +# 在Cocos中使用ECS + BehaviorTree 实现格斗AI 使用过程中有任何问题,可以加QQ群: 552424835 ### 成品展示 demo 角色AI包含了巡逻, 追踪, 攻击, 躲避攻击, 受伤打断攻击, 攻击打断闪避等. 可以细心看一下二图. diff --git a/assets/Scene/helloworld.fire b/assets/Scene/helloworld.fire index fb6c6e7..301f73a 100755 --- a/assets/Scene/helloworld.fire +++ b/assets/Scene/helloworld.fire @@ -75,34 +75,28 @@ "__id__": 5 }, { - "__id__": 8 + "__id__": 7 }, { - "__id__": 10 + "__id__": 9 }, { - "__id__": 18 + "__id__": 17 }, { - "__id__": 26 - }, - { - "__id__": 34 - }, - { - "__id__": 36 + "__id__": 25 } ], "_active": true, "_components": [ { - "__id__": 38 + "__id__": 33 }, { - "__id__": 39 + "__id__": 34 }, { - "__id__": 40 + "__id__": 35 } ], "_prefab": null, @@ -263,24 +257,21 @@ "_components": [ { "__id__": 6 - }, - { - "__id__": 7 } ], "_prefab": null, "_opacity": 255, "_color": { "__type__": "cc.Color", - "r": 135, - "g": 135, - "b": 135, + "r": 255, + "g": 255, + "b": 255, "a": 255 }, "_contentSize": { "__type__": "cc.Size", - "width": 1334, - "height": 750 + "width": 1009, + "height": 454 }, "_anchorPoint": { "__type__": "cc.Vec2", @@ -298,8 +289,8 @@ 0, 0, 1, - 1, - 1, + 1.7, + 1.7, 1 ] }, @@ -316,33 +307,6 @@ "groupIndex": 0, "_id": "e2e0crkOLxGrpMxpbC4iQg1" }, - { - "__type__": "cc.Widget", - "_name": "", - "_objFlags": 0, - "node": { - "__id__": 5 - }, - "_enabled": true, - "alignMode": 0, - "_target": null, - "_alignFlags": 45, - "_left": 0, - "_right": 0, - "_top": 0, - "_bottom": 0, - "_verticalCenter": 0, - "_horizontalCenter": 0, - "_isAbsLeft": true, - "_isAbsRight": true, - "_isAbsTop": true, - "_isAbsBottom": true, - "_isAbsHorizontalCenter": true, - "_isAbsVerticalCenter": true, - "_originalWidth": 200, - "_originalHeight": 150, - "_id": "61Qb7LYvdCYrxlqWxpwiAF" - }, { "__type__": "cc.Sprite", "_name": "", @@ -359,7 +323,7 @@ "_srcBlendFactor": 770, "_dstBlendFactor": 771, "_spriteFrame": { - "__uuid__": "410fb916-8721-4663-bab8-34397391ace7" + "__uuid__": "accc37bc-cb00-4a77-98df-a22077d6ab15" }, "_type": 1, "_sizeMode": 0, @@ -384,7 +348,7 @@ }, "_children": [ { - "__id__": 9 + "__id__": 8 } ], "_active": true, @@ -442,7 +406,7 @@ "_name": "0", "_objFlags": 0, "_parent": { - "__id__": 8 + "__id__": 7 }, "_children": [], "_active": true, @@ -504,13 +468,13 @@ }, "_children": [ { - "__id__": 11 + "__id__": 10 } ], "_active": true, "_components": [ { - "__id__": 16 + "__id__": 15 } ], "_prefab": null, @@ -536,8 +500,8 @@ "__type__": "TypedArray", "ctor": "Float64Array", "array": [ - -503.086, - 245.37, + -585.668, + 320.444, 0, 0, 0, @@ -566,20 +530,20 @@ "_name": "Background", "_objFlags": 512, "_parent": { - "__id__": 10 + "__id__": 9 }, "_children": [ { - "__id__": 12 + "__id__": 11 } ], "_active": true, "_components": [ { - "__id__": 14 + "__id__": 13 }, { - "__id__": 15 + "__id__": 14 } ], "_prefab": null, @@ -635,13 +599,13 @@ "_name": "Label", "_objFlags": 512, "_parent": { - "__id__": 11 + "__id__": 10 }, "_children": [], "_active": true, "_components": [ { - "__id__": 13 + "__id__": 12 } ], "_prefab": null, @@ -697,7 +661,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 12 + "__id__": 11 }, "_enabled": true, "_materials": [ @@ -730,7 +694,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 11 + "__id__": 10 }, "_enabled": true, "_materials": [ @@ -762,7 +726,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 11 + "__id__": 10 }, "_enabled": true, "alignMode": 0, @@ -789,7 +753,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 10 + "__id__": 9 }, "_enabled": true, "_normalMaterial": null, @@ -798,7 +762,7 @@ "zoomScale": 1.2, "clickEvents": [ { - "__id__": 17 + "__id__": 16 } ], "_N$interactable": true, @@ -866,7 +830,7 @@ "__uuid__": "29158224-f8dd-4661-a796-1ffab537140e" }, "_N$target": { - "__id__": 11 + "__id__": 10 }, "_id": "d6HwYkhPdKppYL8wV8YIBf" }, @@ -889,13 +853,13 @@ }, "_children": [ { - "__id__": 19 + "__id__": 18 } ], "_active": true, "_components": [ { - "__id__": 24 + "__id__": 23 } ], "_prefab": null, @@ -921,8 +885,8 @@ "__type__": "TypedArray", "ctor": "Float64Array", "array": [ - -345.923, - 245.37, + -583.658, + 262.887, 0, 0, 0, @@ -951,20 +915,20 @@ "_name": "Background", "_objFlags": 512, "_parent": { - "__id__": 18 + "__id__": 17 }, "_children": [ { - "__id__": 20 + "__id__": 19 } ], "_active": true, "_components": [ { - "__id__": 22 + "__id__": 21 }, { - "__id__": 23 + "__id__": 22 } ], "_prefab": null, @@ -1020,13 +984,13 @@ "_name": "Label", "_objFlags": 512, "_parent": { - "__id__": 19 + "__id__": 18 }, "_children": [], "_active": true, "_components": [ { - "__id__": 21 + "__id__": 20 } ], "_prefab": null, @@ -1082,7 +1046,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 20 + "__id__": 19 }, "_enabled": true, "_materials": [ @@ -1115,7 +1079,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 19 + "__id__": 18 }, "_enabled": true, "_materials": [ @@ -1147,7 +1111,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 19 + "__id__": 18 }, "_enabled": true, "alignMode": 0, @@ -1174,7 +1138,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 18 + "__id__": 17 }, "_enabled": true, "_normalMaterial": null, @@ -1183,7 +1147,7 @@ "zoomScale": 1.2, "clickEvents": [ { - "__id__": 25 + "__id__": 24 } ], "_N$interactable": true, @@ -1251,7 +1215,7 @@ "__uuid__": "29158224-f8dd-4661-a796-1ffab537140e" }, "_N$target": { - "__id__": 19 + "__id__": 18 }, "_id": "63e/kLBnZF/LA3UC/rFE7l" }, @@ -1274,13 +1238,13 @@ }, "_children": [ { - "__id__": 27 + "__id__": 26 } ], "_active": true, "_components": [ { - "__id__": 32 + "__id__": 31 } ], "_prefab": null, @@ -1306,8 +1270,8 @@ "__type__": "TypedArray", "ctor": "Float64Array", "array": [ - 473.095, - 245.37, + -582.95, + 205.33, 0, 0, 0, @@ -1336,20 +1300,20 @@ "_name": "Background", "_objFlags": 512, "_parent": { - "__id__": 26 + "__id__": 25 }, "_children": [ { - "__id__": 28 + "__id__": 27 } ], "_active": true, "_components": [ { - "__id__": 30 + "__id__": 29 }, { - "__id__": 31 + "__id__": 30 } ], "_prefab": null, @@ -1405,13 +1369,13 @@ "_name": "Label", "_objFlags": 512, "_parent": { - "__id__": 27 + "__id__": 26 }, "_children": [], "_active": true, "_components": [ { - "__id__": 29 + "__id__": 28 } ], "_prefab": null, @@ -1467,7 +1431,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 28 + "__id__": 27 }, "_enabled": true, "_materials": [ @@ -1500,7 +1464,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 27 + "__id__": 26 }, "_enabled": true, "_materials": [ @@ -1532,7 +1496,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 27 + "__id__": 26 }, "_enabled": true, "alignMode": 0, @@ -1559,7 +1523,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 26 + "__id__": 25 }, "_enabled": true, "_normalMaterial": null, @@ -1568,7 +1532,7 @@ "zoomScale": 1.2, "clickEvents": [ { - "__id__": 33 + "__id__": 32 } ], "_N$interactable": true, @@ -1636,7 +1600,7 @@ "__uuid__": "29158224-f8dd-4661-a796-1ffab537140e" }, "_N$target": { - "__id__": 27 + "__id__": 26 }, "_id": "749WE4zm1JhpiMAmdyMCeA" }, @@ -1650,196 +1614,6 @@ "handler": "onClick3", "customEventData": "" }, - { - "__type__": "cc.Node", - "_name": "a_role_count", - "_objFlags": 0, - "_parent": { - "__id__": 2 - }, - "_children": [], - "_active": true, - "_components": [ - { - "__id__": 35 - } - ], - "_prefab": null, - "_opacity": 255, - "_color": { - "__type__": "cc.Color", - "r": 255, - "g": 255, - "b": 255, - "a": 255 - }, - "_contentSize": { - "__type__": "cc.Size", - "width": 97.87, - "height": 50.4 - }, - "_anchorPoint": { - "__type__": "cc.Vec2", - "x": 0.5, - "y": 0.5 - }, - "_trs": { - "__type__": "TypedArray", - "ctor": "Float64Array", - "array": [ - -504.601, - 294.479, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1 - ] - }, - "_eulerAngles": { - "__type__": "cc.Vec3", - "x": 0, - "y": 0, - "z": 0 - }, - "_skewX": 0, - "_skewY": 0, - "_is3DNode": false, - "_groupIndex": 0, - "groupIndex": 0, - "_id": "a4JCp5+xFOA4s8fngj8szD" - }, - { - "__type__": "cc.Label", - "_name": "", - "_objFlags": 0, - "node": { - "__id__": 34 - }, - "_enabled": true, - "_materials": [ - { - "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" - } - ], - "_srcBlendFactor": 770, - "_dstBlendFactor": 771, - "_string": "Label", - "_N$string": "Label", - "_fontSize": 40, - "_lineHeight": 40, - "_enableWrapText": true, - "_N$file": null, - "_isSystemFontUsed": true, - "_spacingX": 0, - "_batchAsBitmap": false, - "_styleFlags": 0, - "_underlineHeight": 0, - "_N$horizontalAlign": 1, - "_N$verticalAlign": 1, - "_N$fontFamily": "Arial", - "_N$overflow": 0, - "_N$cacheMode": 0, - "_id": "4417a7mtlNhbcCkscLMkuR" - }, - { - "__type__": "cc.Node", - "_name": "b_role_count", - "_objFlags": 0, - "_parent": { - "__id__": 2 - }, - "_children": [], - "_active": true, - "_components": [ - { - "__id__": 37 - } - ], - "_prefab": null, - "_opacity": 255, - "_color": { - "__type__": "cc.Color", - "r": 255, - "g": 255, - "b": 255, - "a": 255 - }, - "_contentSize": { - "__type__": "cc.Size", - "width": 97.87, - "height": 50.4 - }, - "_anchorPoint": { - "__type__": "cc.Vec2", - "x": 0.5, - "y": 0.5 - }, - "_trs": { - "__type__": "TypedArray", - "ctor": "Float64Array", - "array": [ - -349.693, - 294.479, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1 - ] - }, - "_eulerAngles": { - "__type__": "cc.Vec3", - "x": 0, - "y": 0, - "z": 0 - }, - "_skewX": 0, - "_skewY": 0, - "_is3DNode": false, - "_groupIndex": 0, - "groupIndex": 0, - "_id": "80NAtDFhBOxrIjst58bHAy" - }, - { - "__type__": "cc.Label", - "_name": "", - "_objFlags": 0, - "node": { - "__id__": 36 - }, - "_enabled": true, - "_materials": [ - { - "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" - } - ], - "_srcBlendFactor": 770, - "_dstBlendFactor": 771, - "_string": "Label", - "_N$string": "Label", - "_fontSize": 40, - "_lineHeight": 40, - "_enableWrapText": true, - "_N$file": null, - "_isSystemFontUsed": true, - "_spacingX": 0, - "_batchAsBitmap": false, - "_styleFlags": 0, - "_underlineHeight": 0, - "_N$horizontalAlign": 1, - "_N$verticalAlign": 1, - "_N$fontFamily": "Arial", - "_N$overflow": 0, - "_N$cacheMode": 0, - "_id": "7a9iiLwS1KqqiX/+3BS+Bg" - }, { "__type__": "cc.Canvas", "_name": "", diff --git a/assets/Script/Common/BehaviorTree.ts b/assets/Script/Common/BehaviorTree.ts index 31bceed..1fbedcd 100644 --- a/assets/Script/Common/BehaviorTree.ts +++ b/assets/Script/Common/BehaviorTree.ts @@ -586,7 +586,7 @@ export namespace BT { comMovable.pointIdx = 0; comMovable.points.length = 0; let targetX = node.size.width * Math.random() - node.size.width/2; - let targetY = node.size.height * Math.random() - node.size.height/2; + let targetY = node.size.height * Math.random() - node.size.height/2 - 150; comMovable.points.push(cc.v2(comTrans.x, comTrans.y), cc.v2(targetX, targetY)); comMovable.speed = node.speed; comMovable.speedDirty = true; diff --git a/assets/Script/Core/ECSController.ts b/assets/Script/Core/ECSController.ts index bebbf7c..c159d5f 100644 --- a/assets/Script/Core/ECSController.ts +++ b/assets/Script/Core/ECSController.ts @@ -44,7 +44,7 @@ export class ECSController { new BT.InverterNode(new BT.MonitorNode()), new BT.LockedSequenceNode([ new BT.WaitNode(1.5), - new BT.WalkToRandomPosNode(100, cc.size(view.width - 200, view.height - 200)), + new BT.WalkToRandomPosNode(100, cc.size(view.width - 100, view.height - 300)), ]) ], true), new BT.LockedSequenceNode([ diff --git a/assets/Script/Core/RoleEventProcess.ts b/assets/Script/Core/RoleEventProcess.ts index e0da0e2..daff52b 100644 --- a/assets/Script/Core/RoleEventProcess.ts +++ b/assets/Script/Core/RoleEventProcess.ts @@ -98,8 +98,8 @@ export default class RoleEventProcess extends EventProcess { } this.graphics.lineTo(event.points[0].x, event.points[0].y); this.graphics.stroke(); - - + + event.points.length = 0; } public sync(x: number, y: number, dir: cc.Vec2) { diff --git a/assets/Script/ECS/systems/SysAttack.ts b/assets/Script/ECS/systems/SysAttack.ts index 026df53..bf2c990 100644 --- a/assets/Script/ECS/systems/SysAttack.ts +++ b/assets/Script/ECS/systems/SysAttack.ts @@ -35,11 +35,14 @@ export class SysAttack extends ECSSystem { 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.debugInfo = null; + comAttackable.countDown -= dt; if(comAttackable.countDown <= 0) { comAttackable.dirty = false; @@ -67,10 +70,7 @@ export class SysAttack extends ECSSystem { 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) { @@ -84,6 +84,11 @@ export class SysAttack extends ECSSystem { return false; }) } + + 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.hurtFrameCompleted && comAttackable.countDown <= comAttackable.hurtFrame) { comAttackable.hurtFrameCompleted = true; diff --git a/assets/Script/ECS/systems/SysRoleState.ts b/assets/Script/ECS/systems/SysRoleState.ts index 2976d75..fa29b49 100644 --- a/assets/Script/ECS/systems/SysRoleState.ts +++ b/assets/Script/ECS/systems/SysRoleState.ts @@ -47,8 +47,6 @@ export class SysRoleState extends ECSSystem { comCocosNode.events.push(new EventGraphicsDraw(comAttackable.debugInfo.points, comAttackable.debugInfo.color)); } - - if(comMovable && comMovable.speedDirty) { comMovable.speedDirty = false; if(comMovable.speed > 0) { diff --git a/assets/Script/Main.ts b/assets/Script/Main.ts index 701128d..6dc217a 100644 --- a/assets/Script/Main.ts +++ b/assets/Script/Main.ts @@ -100,5 +100,19 @@ export default class Main extends cc.Component { } + private a() { + let map = {0: 0, 1: 0, 2: 0}; // 出现1的次数 + for(let c=0; c<10000; c++) { + let a = [1, 2, 3]; + a = a.sort((a, b) => Math.random() - 0.5); + for(let i=0; i