master f12859966edf cached
227 files
1.3 MB
424.5k tokens
796 symbols
1 requests
Download .txt
Showing preview only (1,514K chars total). Download the full file or copy to clipboard to get everything.
Repository: kirikayakazuto/CocosCreator_ECS
Branch: master
Commit: f12859966edf
Files: 227
Total size: 1.3 MB

Directory structure:
gitextract_se9l75kc/

├── .gitignore
├── BehaviorTree.dio
├── ECS.dio
├── LICENSE
├── README.md
├── assets/
│   ├── Scene/
│   │   ├── helloworld.fire
│   │   └── helloworld.fire.meta
│   ├── Scene.meta
│   ├── Script/
│   │   ├── Common/
│   │   │   ├── BehaviorTree.ts
│   │   │   ├── BehaviorTree.ts.meta
│   │   │   ├── CocosHelper.ts
│   │   │   ├── CocosHelper.ts.meta
│   │   │   ├── FrameAnimation.ts
│   │   │   └── FrameAnimation.ts.meta
│   │   ├── Common.meta
│   │   ├── Core/
│   │   │   ├── ECSController.ts
│   │   │   ├── ECSController.ts.meta
│   │   │   ├── EventProcess.ts
│   │   │   ├── EventProcess.ts.meta
│   │   │   ├── RoleEventProcess.ts
│   │   │   └── RoleEventProcess.ts.meta
│   │   ├── Core.meta
│   │   ├── ECS/
│   │   │   ├── components/
│   │   │   │   ├── ComAttackable.ts
│   │   │   │   ├── ComAttackable.ts.meta
│   │   │   │   ├── ComBeAttacked.ts
│   │   │   │   ├── ComBeAttacked.ts.meta
│   │   │   │   ├── ComBehaviorTree.ts
│   │   │   │   ├── ComBehaviorTree.ts.meta
│   │   │   │   ├── ComCocosNode.ts
│   │   │   │   ├── ComCocosNode.ts.meta
│   │   │   │   ├── ComMonitor.ts
│   │   │   │   ├── ComMonitor.ts.meta
│   │   │   │   ├── ComMovable.ts
│   │   │   │   ├── ComMovable.ts.meta
│   │   │   │   ├── ComNodeConfig.ts
│   │   │   │   ├── ComNodeConfig.ts.meta
│   │   │   │   ├── ComRoleConfig.ts
│   │   │   │   ├── ComRoleConfig.ts.meta
│   │   │   │   ├── ComTransform.ts
│   │   │   │   └── ComTransform.ts.meta
│   │   │   ├── components.meta
│   │   │   ├── lib/
│   │   │   │   ├── Const.ts
│   │   │   │   ├── Const.ts.meta
│   │   │   │   ├── ECSComponent.ts
│   │   │   │   ├── ECSComponent.ts.meta
│   │   │   │   ├── ECSComponentPool.ts
│   │   │   │   ├── ECSComponentPool.ts.meta
│   │   │   │   ├── ECSFilter.ts
│   │   │   │   ├── ECSFilter.ts.meta
│   │   │   │   ├── ECSSystem.ts
│   │   │   │   ├── ECSSystem.ts.meta
│   │   │   │   ├── ECSWorld.ts
│   │   │   │   └── ECSWorld.ts.meta
│   │   │   ├── lib.meta
│   │   │   ├── systems/
│   │   │   │   ├── SysAttack.ts
│   │   │   │   ├── SysAttack.ts.meta
│   │   │   │   ├── SysBehaviorTree.ts
│   │   │   │   ├── SysBehaviorTree.ts.meta
│   │   │   │   ├── SysCocosView.ts
│   │   │   │   ├── SysCocosView.ts.meta
│   │   │   │   ├── SysMonitor.ts
│   │   │   │   ├── SysMonitor.ts.meta
│   │   │   │   ├── SysMovable.ts
│   │   │   │   ├── SysMovable.ts.meta
│   │   │   │   ├── SysRoleState.ts
│   │   │   │   └── SysRoleState.ts.meta
│   │   │   ├── systems.meta
│   │   │   ├── worlds/
│   │   │   │   ├── WorldCocosView.ts
│   │   │   │   └── WorldCocosView.ts.meta
│   │   │   └── worlds.meta
│   │   ├── ECS.meta
│   │   ├── Main.ts
│   │   ├── Main.ts.meta
│   │   ├── Struct/
│   │   │   ├── Direction.ts
│   │   │   ├── Direction.ts.meta
│   │   │   ├── NodeEvent.ts
│   │   │   └── NodeEvent.ts.meta
│   │   └── Struct.meta
│   ├── Script.meta
│   ├── Texture/
│   │   ├── HelloWorld.png.meta
│   │   └── singleColor.png.meta
│   ├── Texture.meta
│   ├── resources/
│   │   ├── 3de2d4d5-8b98-4175-b44e-2516a9dae308113719czjoklju1eg0ued0.jpeg.meta
│   │   ├── Biker/
│   │   │   ├── Biker.prefab
│   │   │   ├── Biker.prefab.meta
│   │   │   ├── anims/
│   │   │   │   ├── attack.anim
│   │   │   │   ├── attack.anim.meta
│   │   │   │   ├── death.anim
│   │   │   │   ├── death.anim.meta
│   │   │   │   ├── hurt.anim
│   │   │   │   ├── hurt.anim.meta
│   │   │   │   ├── punch.anim
│   │   │   │   ├── punch.anim.meta
│   │   │   │   ├── run.anim
│   │   │   │   ├── run.anim.meta
│   │   │   │   ├── run_attack.anim
│   │   │   │   ├── run_attack.anim.meta
│   │   │   │   ├── stand.anim
│   │   │   │   └── stand.anim.meta
│   │   │   ├── anims.meta
│   │   │   ├── textures/
│   │   │   │   ├── Biker_attack1_01.png.meta
│   │   │   │   ├── Biker_attack1_02.png.meta
│   │   │   │   ├── Biker_attack1_03.png.meta
│   │   │   │   ├── Biker_attack1_04.png.meta
│   │   │   │   ├── Biker_attack1_05.png.meta
│   │   │   │   ├── Biker_attack1_06.png.meta
│   │   │   │   ├── Biker_death_01.png.meta
│   │   │   │   ├── Biker_death_02.png.meta
│   │   │   │   ├── Biker_death_03.png.meta
│   │   │   │   ├── Biker_death_04.png.meta
│   │   │   │   ├── Biker_death_05.png.meta
│   │   │   │   ├── Biker_death_06.png.meta
│   │   │   │   ├── Biker_doublejump_01.png.meta
│   │   │   │   ├── Biker_doublejump_02.png.meta
│   │   │   │   ├── Biker_doublejump_03.png.meta
│   │   │   │   ├── Biker_doublejump_04.png.meta
│   │   │   │   ├── Biker_doublejump_05.png.meta
│   │   │   │   ├── Biker_doublejump_06.png.meta
│   │   │   │   ├── Biker_hurt_01.png.meta
│   │   │   │   ├── Biker_hurt_02.png.meta
│   │   │   │   ├── Biker_idle_01.png.meta
│   │   │   │   ├── Biker_idle_02.png.meta
│   │   │   │   ├── Biker_idle_03.png.meta
│   │   │   │   ├── Biker_idle_04.png.meta
│   │   │   │   ├── Biker_jump_01.png.meta
│   │   │   │   ├── Biker_jump_02.png.meta
│   │   │   │   ├── Biker_jump_03.png.meta
│   │   │   │   ├── Biker_jump_04.png.meta
│   │   │   │   ├── Biker_punch_01.png.meta
│   │   │   │   ├── Biker_punch_02.png.meta
│   │   │   │   ├── Biker_punch_03.png.meta
│   │   │   │   ├── Biker_punch_04.png.meta
│   │   │   │   ├── Biker_punch_05.png.meta
│   │   │   │   ├── Biker_punch_06.png.meta
│   │   │   │   ├── Biker_run_01.png.meta
│   │   │   │   ├── Biker_run_02.png.meta
│   │   │   │   ├── Biker_run_03.png.meta
│   │   │   │   ├── Biker_run_04.png.meta
│   │   │   │   ├── Biker_run_05.png.meta
│   │   │   │   ├── Biker_run_06.png.meta
│   │   │   │   ├── Biker_run_attack_01.png.meta
│   │   │   │   ├── Biker_run_attack_02.png.meta
│   │   │   │   ├── Biker_run_attack_03.png.meta
│   │   │   │   ├── Biker_run_attack_04.png.meta
│   │   │   │   ├── Biker_run_attack_05.png.meta
│   │   │   │   └── Biker_run_attack_06.png.meta
│   │   │   └── textures.meta
│   │   ├── Biker.meta
│   │   ├── Cyborg/
│   │   │   ├── Cyborg.prefab
│   │   │   ├── Cyborg.prefab.meta
│   │   │   ├── anims/
│   │   │   │   ├── attack.anim
│   │   │   │   ├── attack.anim.meta
│   │   │   │   ├── death.anim
│   │   │   │   ├── death.anim.meta
│   │   │   │   ├── hurt.anim
│   │   │   │   ├── hurt.anim.meta
│   │   │   │   ├── punch.anim
│   │   │   │   ├── punch.anim.meta
│   │   │   │   ├── run.anim
│   │   │   │   ├── run.anim.meta
│   │   │   │   ├── run_attack.anim
│   │   │   │   ├── run_attack.anim.meta
│   │   │   │   ├── stand.anim
│   │   │   │   └── stand.anim.meta
│   │   │   ├── anims.meta
│   │   │   ├── textures/
│   │   │   │   ├── Cyborg_attack1_01.png.meta
│   │   │   │   ├── Cyborg_attack1_02.png.meta
│   │   │   │   ├── Cyborg_attack1_03.png.meta
│   │   │   │   ├── Cyborg_attack1_04.png.meta
│   │   │   │   ├── Cyborg_attack1_05.png.meta
│   │   │   │   ├── Cyborg_attack1_06.png.meta
│   │   │   │   ├── Cyborg_death_01.png.meta
│   │   │   │   ├── Cyborg_death_02.png.meta
│   │   │   │   ├── Cyborg_death_03.png.meta
│   │   │   │   ├── Cyborg_death_04.png.meta
│   │   │   │   ├── Cyborg_death_05.png.meta
│   │   │   │   ├── Cyborg_death_06.png.meta
│   │   │   │   ├── Cyborg_doublejump_01.png.meta
│   │   │   │   ├── Cyborg_doublejump_02.png.meta
│   │   │   │   ├── Cyborg_doublejump_03.png.meta
│   │   │   │   ├── Cyborg_doublejump_04.png.meta
│   │   │   │   ├── Cyborg_doublejump_05.png.meta
│   │   │   │   ├── Cyborg_doublejump_06.png.meta
│   │   │   │   ├── Cyborg_hurt_01.png.meta
│   │   │   │   ├── Cyborg_hurt_02.png.meta
│   │   │   │   ├── Cyborg_idle_01.png.meta
│   │   │   │   ├── Cyborg_idle_02.png.meta
│   │   │   │   ├── Cyborg_idle_03.png.meta
│   │   │   │   ├── Cyborg_idle_04.png.meta
│   │   │   │   ├── Cyborg_jump_01.png.meta
│   │   │   │   ├── Cyborg_jump_02.png.meta
│   │   │   │   ├── Cyborg_jump_03.png.meta
│   │   │   │   ├── Cyborg_jump_04.png.meta
│   │   │   │   ├── Cyborg_punch_01.png.meta
│   │   │   │   ├── Cyborg_punch_02.png.meta
│   │   │   │   ├── Cyborg_punch_03.png.meta
│   │   │   │   ├── Cyborg_punch_04.png.meta
│   │   │   │   ├── Cyborg_punch_05.png.meta
│   │   │   │   ├── Cyborg_punch_06.png.meta
│   │   │   │   ├── Cyborg_run_01.png.meta
│   │   │   │   ├── Cyborg_run_02.png.meta
│   │   │   │   ├── Cyborg_run_03.png.meta
│   │   │   │   ├── Cyborg_run_04.png.meta
│   │   │   │   ├── Cyborg_run_05.png.meta
│   │   │   │   ├── Cyborg_run_06.png.meta
│   │   │   │   ├── Cyborg_run_attack_01.png.meta
│   │   │   │   ├── Cyborg_run_attack_02.png.meta
│   │   │   │   ├── Cyborg_run_attack_03.png.meta
│   │   │   │   ├── Cyborg_run_attack_04.png.meta
│   │   │   │   ├── Cyborg_run_attack_05.png.meta
│   │   │   │   └── Cyborg_run_attack_06.png.meta
│   │   │   └── textures.meta
│   │   ├── Cyborg.meta
│   │   ├── item.prefab
│   │   └── item.prefab.meta
│   └── resources.meta
├── creator.d.ts
├── jsconfig.json
├── project.json
├── role1behaviortree.dio
├── settings/
│   ├── builder.json
│   ├── builder.panel.json
│   ├── project.json
│   └── services.json
├── template.json
├── tsconfig.json
└── 行为树决策的时效性.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
#/////////////////////////////////////////////////////////////////////////////
# Fireball Projects
#/////////////////////////////////////////////////////////////////////////////

/library/
/temp/
/local/
/build/

#/////////////////////////////////////////////////////////////////////////////
# npm files
#/////////////////////////////////////////////////////////////////////////////

npm-debug.log
node_modules/

#/////////////////////////////////////////////////////////////////////////////
# Logs and databases
#/////////////////////////////////////////////////////////////////////////////

*.log
*.sql
*.sqlite

#/////////////////////////////////////////////////////////////////////////////
# files for debugger
#/////////////////////////////////////////////////////////////////////////////

*.sln
*.pidb
*.suo

#/////////////////////////////////////////////////////////////////////////////
# OS generated files
#/////////////////////////////////////////////////////////////////////////////

.DS_Store
ehthumbs.db
Thumbs.db

#/////////////////////////////////////////////////////////////////////////////
# WebStorm files
#/////////////////////////////////////////////////////////////////////////////

.idea/

#//////////////////////////
# VS Code files
#//////////////////////////

.vscode/


================================================
FILE: BehaviorTree.dio
================================================
<mxfile host="65bd71144e">
    <diagram id="dLwbfvz9vYh7qeJd_Tvh" name="第 1 页">
        <mxGraphModel dx="647" dy="612" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1920" pageHeight="1200" math="0" shadow="0">
            <root>
                <mxCell id="0"/>
                <mxCell id="1" parent="0"/>
                <mxCell id="2" value="ECS" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="340" y="40" width="80" height="40" as="geometry"/>
                </mxCell>
                <mxCell id="3" value="检查是有有钥匙" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="210" y="350" width="80" height="40" as="geometry"/>
                </mxCell>
                <mxCell id="6" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="3">
                    <mxGeometry relative="1" as="geometry"/>
                </mxCell>
                <mxCell id="8" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="7">
                    <mxGeometry relative="1" as="geometry"/>
                </mxCell>
                <mxCell id="4" value="Sequence" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="270" y="260" width="80" height="40" as="geometry"/>
                </mxCell>
                <mxCell id="7" value="钥匙开门" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="330" y="350" width="80" height="40" as="geometry"/>
                </mxCell>
                <mxCell id="10" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="4">
                    <mxGeometry relative="1" as="geometry"/>
                </mxCell>
                <mxCell id="12" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="11">
                    <mxGeometry relative="1" as="geometry"/>
                </mxCell>
                <mxCell id="9" value="Select" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="330" y="170" width="80" height="40" as="geometry"/>
                </mxCell>
                <mxCell id="11" value="斧头砸门" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="390" y="260" width="80" height="40" as="geometry"/>
                </mxCell>
                <mxCell id="13" value="Cocos" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="490" y="40" width="80" height="40" as="geometry"/>
                </mxCell>
                <mxCell id="14" value="" style="shape=cross;whiteSpace=wrap;html=1;size=0;" vertex="1" parent="1">
                    <mxGeometry x="440" y="40" width="30" height="35" as="geometry"/>
                </mxCell>
            </root>
        </mxGraphModel>
    </diagram>
</mxfile>

================================================
FILE: ECS.dio
================================================
<mxfile host="65bd71144e">
    <diagram id="TQPzfji1_PItH667R2By" name="第 1 页">
        <mxGraphModel dx="783" dy="741" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="583" pageHeight="413" math="0" shadow="0">
            <root>
                <mxCell id="0"/>
                <mxCell id="1" parent="0"/>
                <mxCell id="12" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="3">
                    <mxGeometry relative="1" as="geometry"/>
                </mxCell>
                <mxCell id="52" value="1:n" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="12">
                    <mxGeometry x="-0.0168" relative="1" as="geometry">
                        <mxPoint as="offset"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="45" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;startSize=0;" edge="1" parent="1" source="2" target="5">
                    <mxGeometry relative="1" as="geometry"/>
                </mxCell>
                <mxCell id="51" value="1:n" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="45">
                    <mxGeometry x="-0.2487" relative="1" as="geometry">
                        <mxPoint y="-1" as="offset"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="2" value="World" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="310" y="10" width="120" height="60" as="geometry"/>
                </mxCell>
                <mxCell id="49" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;startSize=0;" edge="1" parent="1" source="3" target="47">
                    <mxGeometry relative="1" as="geometry"/>
                </mxCell>
                <mxCell id="50" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;startSize=0;" edge="1" parent="1" source="3" target="48">
                    <mxGeometry relative="1" as="geometry"/>
                </mxCell>
                <mxCell id="3" value="System" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="150" y="146" width="120" height="60" as="geometry"/>
                </mxCell>
                <mxCell id="9" value="1:n" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="5" target="7">
                    <mxGeometry relative="1" as="geometry"/>
                </mxCell>
                <mxCell id="5" value="Entity" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="400" y="146" width="120" height="60" as="geometry"/>
                </mxCell>
                <mxCell id="56" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;startSize=0;" edge="1" parent="1" source="7" target="54">
                    <mxGeometry relative="1" as="geometry"/>
                </mxCell>
                <mxCell id="57" style="edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;startSize=0;" edge="1" parent="1" source="7" target="55">
                    <mxGeometry relative="1" as="geometry"/>
                </mxCell>
                <mxCell id="7" value="Component" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="400" y="260" width="120" height="60" as="geometry"/>
                </mxCell>
                <mxCell id="13" value="" style="shape=table;html=1;whiteSpace=wrap;startSize=0;container=1;collapsible=0;childLayout=tableLayout;" vertex="1" parent="1">
                    <mxGeometry x="560" y="520" width="340" height="140" as="geometry"/>
                </mxCell>
                <mxCell id="14" value="" style="shape=partialRectangle;html=1;whiteSpace=wrap;collapsible=0;dropTarget=0;pointerEvents=0;fillColor=none;top=0;left=0;bottom=0;right=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;" vertex="1" parent="13">
                    <mxGeometry width="340" height="47" as="geometry"/>
                </mxCell>
                <mxCell id="15" value="" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="14">
                    <mxGeometry width="82" height="47" as="geometry">
                        <mxRectangle width="82" height="47" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="16" value="Component1" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="14">
                    <mxGeometry x="82" width="61" height="47" as="geometry">
                        <mxRectangle width="61" height="47" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="17" value="Component2" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="14">
                    <mxGeometry x="143" width="64" height="47" as="geometry">
                        <mxRectangle width="64" height="47" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="39" value="Component3" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="14">
                    <mxGeometry x="207" width="64" height="47" as="geometry">
                        <mxRectangle width="64" height="47" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="42" value="Component4" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="14">
                    <mxGeometry x="271" width="69" height="47" as="geometry">
                        <mxRectangle width="69" height="47" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="18" value="" style="shape=partialRectangle;html=1;whiteSpace=wrap;collapsible=0;dropTarget=0;pointerEvents=0;fillColor=none;top=0;left=0;bottom=0;right=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;" vertex="1" parent="13">
                    <mxGeometry y="47" width="340" height="46" as="geometry"/>
                </mxCell>
                <mxCell id="19" value="&lt;span&gt;entity1&lt;/span&gt;" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="18">
                    <mxGeometry width="82" height="46" as="geometry">
                        <mxRectangle width="82" height="46" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="20" value="1" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="18">
                    <mxGeometry x="82" width="61" height="46" as="geometry">
                        <mxRectangle width="61" height="46" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="21" value="1" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="18">
                    <mxGeometry x="143" width="64" height="46" as="geometry">
                        <mxRectangle width="64" height="46" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="40" value="0" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="18">
                    <mxGeometry x="207" width="64" height="46" as="geometry">
                        <mxRectangle width="64" height="46" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="43" value="1" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="18">
                    <mxGeometry x="271" width="69" height="46" as="geometry">
                        <mxRectangle width="69" height="46" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="22" value="" style="shape=partialRectangle;html=1;whiteSpace=wrap;collapsible=0;dropTarget=0;pointerEvents=0;fillColor=none;top=0;left=0;bottom=0;right=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;" vertex="1" parent="13">
                    <mxGeometry y="93" width="340" height="47" as="geometry"/>
                </mxCell>
                <mxCell id="23" value="&lt;span&gt;entity2&lt;/span&gt;" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="22">
                    <mxGeometry width="82" height="47" as="geometry">
                        <mxRectangle width="82" height="47" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="24" value="0" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="22">
                    <mxGeometry x="82" width="61" height="47" as="geometry">
                        <mxRectangle width="61" height="47" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="25" value="1" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="22">
                    <mxGeometry x="143" width="64" height="47" as="geometry">
                        <mxRectangle width="64" height="47" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="41" value="1" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="22">
                    <mxGeometry x="207" width="64" height="47" as="geometry">
                        <mxRectangle width="64" height="47" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="44" value="0" style="shape=partialRectangle;html=1;whiteSpace=wrap;connectable=0;fillColor=none;top=0;left=0;bottom=0;right=0;overflow=hidden;pointerEvents=1;" vertex="1" parent="22">
                    <mxGeometry x="271" width="69" height="47" as="geometry">
                        <mxRectangle width="69" height="47" as="alternateBounds"/>
                    </mxGeometry>
                </mxCell>
                <mxCell id="47" value="System1" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="60" y="248" width="120" height="60" as="geometry"/>
                </mxCell>
                <mxCell id="48" value="System2" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="220" y="248" width="120" height="60" as="geometry"/>
                </mxCell>
                <mxCell id="54" value="Component1" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="320" y="360" width="120" height="60" as="geometry"/>
                </mxCell>
                <mxCell id="55" value="Component2" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
                    <mxGeometry x="480" y="360" width="120" height="60" as="geometry"/>
                </mxCell>
            </root>
        </mxGraphModel>
    </diagram>
</mxfile>

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2024 honmono

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# 在Cocos中使用ECS + BehaviorTree 实现格斗AI  使用过程中有任何问题,可以加QQ群: 552424835
### 成品展示

demo 角色AI包含了巡逻, 追踪, 攻击, 躲避攻击, 受伤打断攻击, 攻击打断闪避等. 可以细心看一下二图.

巡逻中

<img src="./images/巡逻.gif" title="" alt="巡逻.gif" width="501">

追逐打斗

<img src="./images/打斗.gif" title="" alt="打斗.gif" width="507">



完整展示视频链接: 

https://www.bilibili.com/video/bv1hi4y1Q7Uv



代码链接在文章末位.



### 1. 写一个ECS框架

**ECS** 全称 Entity - Component - System(实体 - 组件 - 系统).  

**组件只有属性没有行为, 系统只有行为没有属性.**

-------

本来这里想介绍一下ECS的概念,  但是写起来感觉像是记流水账, 网上已经有很多ECS的介绍文章了, 所以觉得不如贴几篇我个人觉得写的好的, 谈一谈我的理解. 

[浅谈《守望先锋》中的 ECS 构架](https://blog.codingnow.com/2017/06/overwatch_ecs.html)

这篇文章应该是最早一批介绍ECS架构的文章了, 看过好几遍, 不仅全面的介绍了ECS架构, 还对比了ECS和传统游戏开发架构的区别. 以及在网络同步时的处理.

[游戏开发中的ECS 架构概述](https://zhuanlan.zhihu.com/p/30538626)

这篇文章比较接地气

> ***ECS***,即 Entity-Component-System(实体-组件-系统) 的缩写,其模式遵循[组合优于继承](https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Composition_over_inheritance)原则,游戏内的每一个基本单元都是一个**实体**,每个**实体**又由一个或多个**组件**构成,每个**组件**仅仅包含代表其特性的数据(即在组件中没有任何方法),例如:移动相关的组件`MoveComponent`包含速度、位置、朝向等属性,一旦一个实体拥有了`MoveComponent`组件便可以认为它拥有了移动的能力,**系统**便是来处理拥有一个或多个相同**组件**的**实体**集合的工具,其只拥有行为(即在系统中没有任何数据),在这个例子中,处理移动的**系统**仅仅关心拥有移动能力的**实体**,它会遍历所有拥有`MoveComponent`**组件**的**实体**,并根据相关的数据(速度、位置、朝向等),更新实体的位置。
> 
> **实体**与**组件**是一个一对多的关系,**实体**拥有怎样的能力,完全是取决于其拥有哪些**组件**,通过动态添加或删除**组件**,可以在(游戏)运行时改变**实体**的行为。



**这段话对于ECS的关系也是我设计的框架遵守的规则.** 即Component只包含属性, System只包含行为.



#### 1. 这个ECS框架做了什么

World-Entity-Component-System的关系图

<img src="./images/2022-03-29-19-16-28-image.png" title="" alt="" width="441">

**World每帧根据顺序调用所有的System, System中会处理对应的Component. 在这个过程中, 使用者可以动态的创建或销毁Entity, 给Entity添加或移除Component.**



为了更高效的维护Entity-Component-System的关系, 我采取了一些办法.

###### 1. 所有的Component都通过其对应的ComponentPool维护.

例如MoveComponent会生成一个MoveComponentPool进行维护, 方便实现复用. 外面不直接持有Component, 而是通过component在pool中的index索引便可以在对应的pool中获取到对应的Component.

###### 2. Entity使用自增Id标识.

外部不需要持有Entity对象, 或者说没有Entity对象, 所有的Entity都是一个Id, 通过这个Id在world内进行操作.

###### 3. System通过Filter类管理关注的Entity.

上文中提到System为了处理其关心的ComponentA, 会遍历所有拥有该ComponentA的Entity. 但是怎么判断哪下Entity有这个ComponentA呢?  传统的方法会遍历所有的Entity, 判断其是否有ComponentA, 这种方案明显是不够高效的. 所以这里引入了Filter类, 其方法的核心是空间换时间并有一套判断规则(接收某些类型的组件, 拒接某些类型的组件), 当每次进行AddComponent和RemoveComponent 或者RemoveEntity等会影响实体的操作时, 会通知所有的Filter有实体进行了修改,Filter会判断该实体是否还符合条件(也就是判断是否有ComponentA), 选择是否在Filter中保留该实体. 那么当System需要遍历某些特定的Entity时, 就可以直接通过对应的Filter就可以获得了.

###### 4. Entity和Component的关系可以用一张二维表维护.

|         | ComponentA | ComponentB | ComponentC | ComponentD |
|:-------:|:----------:|:----------:|:----------:|:----------:|
| Entity1 | -1         | 0          | -1         | 0          |
| Entity2 | -1         | 1          | 0          | -1         |

如上述表格中Component数字的意思是其在Pool中的index索引, -1表示没有.

所以Entity1有组件ComponentB, ComponentD.Entity1有组件ComponentB, ComponentC.

**还有最后一个问题就是 如何将Entity和Component转换成0~N的整数以方便构建二维数组呢?**

对于Entity可以通过id的自增实现, 每创建一个Entity, id++.

而Component可以根据类型的枚举值得到唯一标识. 如下面的枚举值.

```typescript
export enum ComType {
    ComCocosNode = 0,
    ComMovable = 1,
    ComNodeConfig = 2,
    ComBehaviorTree = 3,
    ComTransform = 4,
    ComMonitor = 5,
    ComRoleConfig = 6,
    ComAttackable = 7,
    ComBeAttacked = 8
}
```

这样就可以构建出上面的二维表了.



最后还可以通过ts的注解, 将ComType注入到对应的Component类中. 将type和component一一对应起来.

```typescript
// 项目中一个Component.
@ECSComponent(ComType.ComMovable)
export class ComMovable {
    public running = false;
    public speed = 0;
    public points: cc.Vec2[] = [];
    public pointIdx = 0;
    public keepDir = false;
    public speedDirty = false;
}
```

###### 小结: 到这一步就已经完成框架部分了, 再展示一下ComMovable对应的SysMovable. 这个System会每帧根据ComMovable的当前状态, 计算出下一帧的ComMovable状态.

这里插入一下对于Filter的更详细的介绍, Filter的判断规则是通过参数判断接收某些类型的组件, 拒接某些类型的组件.  比如这个参数[ComMovable, ComTransform, ComCocosNode])表示这个Filter保存的是同时含有ComMovable,ComTransform,ComCocosNode组件的实体.

```
const FILTER_MOVE = GenFilterKey([ComMovable, ComTransform, ComCocosNode]);
export class SysMovable extends ECSSystem {
    /** 更新 */
    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;
                }
                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;
            }
            if(comMovable.pointIdx >= comMovable.points.length) {
                comMovable.speed = 0;
                comMovable.speedDirty = true;
            }
            return false;
        });
    }
}
```



#### 2. ECS框架和Cocos Creator结合

<img title="" src="./images/2022-03-30-01-04-53-image.png" alt="" width="343">

ECS框架本身的实现不难, 核心代码只有几百行的样子, 但是如何将这个框架和Cocos Creator结合起来, 或者说怎么展示一个Node, 并可以通过ECS的方式操控Node呢?



以上面的ComMovable和SysMovable为例, ECS本身更多的是数据上的逻辑处理,  Entity添加了ComMovable组件就获得了SysMovable的能力, 那么给Entity添加一个显示Node的组件(ComCocosNode), 在通过一个处理ComCocosNode的System(SysCocosView)是不是就实现了展示node的能力呢.



###### 1. 设计结合Cocos中Node的组件

基于这个想法我设计了ComCocosNode.

```typescript
@ECSComponent(ComType.ComCocosNode)
export class ComCocosNode {
    public node: cc.Node = null;
    public loaded = false;
    public events: EventBase[] = [];
}
```

ComCocosNode中有node属性. 通过Entity获取到ComCocosNode组件就可以修改node的属性了, 而events是因为对于node我们不仅有同步的处理, 也有一些异步的处理, 比如播放一系列动画, 这种可以通过添加事件的方式, 即在system不直接调用node的组件方法, 而是让组件自己读取event, 自己去处理. 



这个时候node还没有赋值, 所以我又设计了一个组件ComNodeConfig

```typescript
@ECSComponent(ComType.ComNodeConfig)
export class ComNodeConfig {
    id = 0;                 // 唯一标识
    prefabUrl = '' 
    layer = 0;              // 层级
}
```

这里可能会有人有疑问, 为什么不把这两个组件的属性合并到一起, 这个其实是为了方便配置, ComNodeConfig的属性都是可以直接配置在表上的, 这样的话就方便配置同学了.



###### 2. 设计处理ComNodeConfig的System

最后通过一个SysCocosView系统, 这个系统处理的实体是 有ComNodeConfig组件, 但是没有ComCocosNode组件的实体.  每次遍历时根据ComNodeConfig组件的prefabUrl加载prefab生成node, 根据layer层级将node添加到指定位置, 然后给这个实体添加ComCocosNode组件, 将node值赋上. 这样下一次就不会处理这个实体了.  下面的代码是demo已经完成后的代码了, 我就不还原到刚开始时候的样子了.

```typescript
const FILTER_COCOS_NODE = GenFillterKey([ComNodeConfig], [ComCocosNode]);
const FILTER_NODE_EVENT = GenFillterKey([ComCocosNode, ComTransform]);
export class SysCocosView extends ECSSystem implements ITouchProcessor {

    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;
        });
    }
}
```



### 写一个BehaviorTree(行为树)

###### 1. BehaviroTree是什么?

介绍行为树网上也有很多文章了, 我这里也就不赘述了.

[游戏AI之决策结构—行为树 - KillerAery - 博客园](https://www.cnblogs.com/KillerAery/p/10007887.html)

[AI 行为树的工作原理 | indienova 独立游戏](https://indienova.com/indie-game-development/ai-behavior-trees-how-they-work/)

> 行为树的名字很好地解释了它是什么。不像有限状态机(Finite State Machine)或其他用于 AI 编程的系统,行为树是一棵用于控制 AI 决策行为的、包含了层级节点的树结构。树的最末端——叶子,就是这些 AI 实际上去做事情的命令;连接树叶的树枝,就是各种类型的节点,这些节点决定了 AI 如何从树的顶端根据不同的情况,来沿着不同的路径来到最终的叶子这一过程。
> 
> 行为树可以非常地“深”,层层节点向下延伸。凭借调用实现具体功能的子行为树,开发者可以建立相互连接的行为树库来做出非常让人信服的 AI 行为。并且,行为树的开发是高度迭代的,你可以从一个很简单的行为开始,然后做一些分支来应对不同的情境或是实现不同的目标,让 AI 的诉求来驱动行为,或是允许 AI 在行为树没有覆盖到的情境下使用备用方案等等。

树的最末端叶子是AI实际上做的事的命令可以称为行为, 行为是需要用户编写的具体的动作, 比如移动到某位置, 攻击, 闪避等.  联系根到叶子的节点的中间节点可以称为决策节点, 决策节点并没有实际的行为,而是决定是否可以向下执行到叶子节点.



如何决定呢?

每一个结点执行后都会返回一个状态, 状态有三种1, Success. 2, Fail. 3, Running.

Success和Fail很好理解, 比如一个监视节点, 看到了敌人返回success, 没看到返回Fail.

但是对于一个需要执行一段时间的节点, 比如1s内移动五步, 在不到1s时去看节点的状态, 这个时候返回成功或者失败都是不合理的, 所以这种情况应该返回Running表示这个节点还在执行中. 等下一帧在继续判断.



这个时候我们可以设计这样一个节点, 它的状态是和子节点状态挂钩的, 按顺序执行子节点,如果遇到了执行失败的结点则返回失败, 如果全部执行成功则返回成功. 这种结点可以称为Sequence.

类似的结点还有Select, 这个节点的状态是按顺序执行子节点,如果全部执行失败则返回失败, 如果遇到执行成功则返回成功.

下面是一个实际项目Sequence的实现.

```typescript
/** Sequence node */
NodeHandlers[NodeType.Sequence] = {
    onEnter(node: SequenceNode, context: ExecuteContext) : void {
        node.currIdx = 0;
        context.executor.onEnterBTNode(node.children[node.currIdx], context);
        node.state = NodeState.Executing;
    },
    onUpdate(node: SequenceNode, context: ExecuteContext) : void {
        if(node.currIdx < 0 || node.currIdx >= node.children.length) {
            // 越界了, 不应该发生, 直接认为是失败了
            node.state = NodeState.Fail;
            return;
        }
        // 检查前置条件是否满足
        for(let i=0; i<node.currIdx; i++) {
            context.executor.updateBTNode(node.children[i], context);
            if(node.children[i].state !== NodeState.Success) return;
        }
        context.executor.updateBTNode(node.children[node.currIdx], context);
        let state = node.children[node.currIdx].state;
        if(state == NodeState.Executing) return;

        if(state === NodeState.Fail && !node.ignoreFailure) {
            node.state = NodeState.Fail;
            return;
        }
        if(state === NodeState.Success && node.currIdx == node.children.length-1) {
            node.state = NodeState.Success;
            return ;
        }
        context.executor.onEnterBTNode(node.children[++node.currIdx], context);
    }
};
```



这两个结点的组合就可以实现if else的效果, 如角色在门前, 如果有钥匙就开门, 如果没有就砸门.  实现如下图

如果有钥匙, Sequence的第一个子节点执行成功, 那么会去执行第二个子节点(钥匙开门).

Sequence执行成功, 就不会执行后面的斧头砸门节点. 如果没有钥匙, Sequence执行失败, 那么就执行后面的斧头砸门节点.

<img src="./images/2022-03-30-00-58-10-image.png" title="" alt="" width="317">



###### 2. 决策的时效性

根据我看的一些文档, 对于行为树的决策是每一帧都要更新的, 比如现在有一个场景, 用户可以输入文本, 输入move让方块A向前移动10格子, 输入stop方块A停止移动. 那么对于行为树来说, 每一帧都要判断当前用户输入的是move,还是stop, 从而下达是移动还是停止的行为.

对于移动, 行为是sequence([用户输入move, 移动]); 用ActionA代替

对于停止, 行为是sequence([用户输入stop, 停止]);用ActionB代替

最终行为是select([ActionA, ActionB])

> sequence表示按顺序执行子行为, 如果遇到子行为执行失败, 那么立刻停止, 并返回失败, 如果全部执行成功, 那么返回成功.

> select表示按顺序执行子行为, 如果遇到子行为执行成功, 那么立即停止, 并返回成功. 如果全部执行失败, 那么返回失败.

假设现在用户点击一下, 那么每帧都需要从头一层层向下判断执行, 直到判断到移动再执行.

当然这是有必要的, 对于行为来说 确定自己能否应该执行是十分重要的.

但是这对执行一个 持续性的行为很不友好. 假设还是上面的场景, 用户输入sleep, 方块停止移动2s. 就是sequence([用户输入sleep, 停止移动2s]). 这个时候行为树是 select([ActionA, ActionB, ActionC]);

那么当我输入sleep, 方块停止移动的时间内, 输入move, 那么下一帧的决策就进入了ActionA, 导致方块移动. 停止移动2s的行为被打断了.

这个问题我称为行为树决策的时效性, 也就是行为得到的决策, 并不能维持一定时间.

这个决策其实目前只是sequence和Select 才拥有的.

## 如何解决:

因为我是自己想的, 所以解决方案可能不是最优的.

首先我加入了具有时效性的LockedSequence, LockedSelect, 也就是当前行为的决策一旦做出, 就必须在当前行为完全结束后才能被修改.

```
class NodeHandler {

onEnter:(node: NodeBase, context: ExecuteContext) => void;

onUpdate:(node: NodeBase, context: ExecuteContext) => void;

}
```

引入一丢丢代码, 在onEnter时, 将当前行为的状态置为 running, 在onUpdate时判断, 如果当前状态不是running就return. 所以一旦状态确定, 就不会再onUpdate中被修改, 直到下一次进入onEnter.

这个时候在带入上述的场景就没问题了, 当用户输入sleep时, 方块停止移动2s, 在2s内输入move, 并不会导致ActionC的决策更改, 直到停止移动2s的行为结束, 进入下一个周期后才会进入ActionA

但是这个同样也导致了另一个问题, 就是并行的行为. 比如假设一个场景, 士兵一边巡逻, 一边观察是否有敌人, 如果有敌人, 那么停止巡逻, 去追击敌人.

行为树如下:

ActionA = 巡逻

ActionB = sequence([观察是否有敌人, 追击敌人]);

repeat(sequence([ActionB, ActionA]))

因为上面的方法在行为结束前不会修改决策, 那么就会出现, 士兵先观察是否有敌人, 没有就去巡逻, 巡逻完了, 再去观察是否有敌人, 这就太蠢了.

我解决上面的问题的方案是添加一个新的决策Node, 这个Node就是处理并行行为的.

parallel 的能力是 顺序处理子节点, 但是并不需要等待前一个节点执行完毕后才能执行后一个. 当有行为返回失败时, 立即退出返回失败, 当所有行为返回成功时, 停止返回成功.

行为树如下:

repeat(selector([parallel([Inverter(观察是否有敌人), 巡逻]), 追击敌人]))

> Inverter表示取反

当前没有发现有敌人, 那么行为在巡逻, parallel还在running阶段, 因为巡逻不会失败, 所以最后一种情况是 如果发现敌人, 那么parallel立即返回失败, 那么行为就到了追击敌人了.



最后展示一下Demo中的行为树.

![](./images/2022-03-30-01-11-22-image.png)



================================================
FILE: assets/Scene/helloworld.fire
================================================
[
  {
    "__type__": "cc.SceneAsset",
    "_name": "",
    "_objFlags": 0,
    "_native": "",
    "scene": {
      "__id__": 1
    }
  },
  {
    "__type__": "cc.Scene",
    "_objFlags": 0,
    "_parent": null,
    "_children": [
      {
        "__id__": 2
      }
    ],
    "_active": false,
    "_components": [],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 0,
      "height": 0
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0,
      "y": 0
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        1,
        1,
        1
      ]
    },
    "_is3DNode": true,
    "_groupIndex": 0,
    "groupIndex": 0,
    "autoReleaseAssets": false,
    "_id": "2d2f792f-a40c-49bb-a189-ed176a246e49"
  },
  {
    "__type__": "cc.Node",
    "_name": "Canvas",
    "_objFlags": 0,
    "_parent": {
      "__id__": 1
    },
    "_children": [
      {
        "__id__": 3
      },
      {
        "__id__": 5
      },
      {
        "__id__": 7
      },
      {
        "__id__": 9
      },
      {
        "__id__": 17
      },
      {
        "__id__": 25
      }
    ],
    "_active": true,
    "_components": [
      {
        "__id__": 33
      },
      {
        "__id__": 34
      },
      {
        "__id__": 35
      }
    ],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 252,
      "g": 252,
      "b": 252,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 1334,
      "height": 750
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        667,
        375,
        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": "a286bbGknJLZpRpxROV6M94"
  },
  {
    "__type__": "cc.Node",
    "_name": "Main Camera",
    "_objFlags": 0,
    "_parent": {
      "__id__": 2
    },
    "_children": [],
    "_active": true,
    "_components": [
      {
        "__id__": 4
      }
    ],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 0,
      "height": 0
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        0,
        0,
        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": "8bvRvaGVFERoHtu4cZv9yg"
  },
  {
    "__type__": "cc.Camera",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 3
    },
    "_enabled": true,
    "_cullingMask": 4294967295,
    "_clearFlags": 7,
    "_backgroundColor": {
      "__type__": "cc.Color",
      "r": 0,
      "g": 0,
      "b": 0,
      "a": 255
    },
    "_depth": -1,
    "_zoomRatio": 1,
    "_targetTexture": null,
    "_fov": 60,
    "_orthoSize": 10,
    "_nearClip": 1,
    "_farClip": 4096,
    "_ortho": true,
    "_rect": {
      "__type__": "cc.Rect",
      "x": 0,
      "y": 0,
      "width": 1,
      "height": 1
    },
    "_renderStages": 1,
    "_alignWithScreen": true,
    "_id": "fa1jZPSrpI9okejGyzR6xc"
  },
  {
    "__type__": "cc.Node",
    "_name": "background",
    "_objFlags": 0,
    "_parent": {
      "__id__": 2
    },
    "_children": [],
    "_active": true,
    "_components": [
      {
        "__id__": 6
      }
    ],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 1009,
      "height": 454
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        1.7,
        1.7,
        1
      ]
    },
    "_eulerAngles": {
      "__type__": "cc.Vec3",
      "x": 0,
      "y": 0,
      "z": 0
    },
    "_skewX": 0,
    "_skewY": 0,
    "_is3DNode": false,
    "_groupIndex": 0,
    "groupIndex": 0,
    "_id": "e2e0crkOLxGrpMxpbC4iQg1"
  },
  {
    "__type__": "cc.Sprite",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 5
    },
    "_enabled": true,
    "_materials": [
      {
        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
      }
    ],
    "_srcBlendFactor": 770,
    "_dstBlendFactor": 771,
    "_spriteFrame": {
      "__uuid__": "accc37bc-cb00-4a77-98df-a22077d6ab15"
    },
    "_type": 1,
    "_sizeMode": 0,
    "_fillType": 0,
    "_fillCenter": {
      "__type__": "cc.Vec2",
      "x": 0,
      "y": 0
    },
    "_fillStart": 0,
    "_fillRange": 0,
    "_isTrimmedMode": true,
    "_atlas": null,
    "_id": "39uSEgVOVLgrNU+v+Ag+nR"
  },
  {
    "__type__": "cc.Node",
    "_name": "Layers",
    "_objFlags": 0,
    "_parent": {
      "__id__": 2
    },
    "_children": [
      {
        "__id__": 8
      }
    ],
    "_active": true,
    "_components": [],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 0,
      "height": 0
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        0,
        0,
        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": "e0rMWkiTBEKbXDwMY3m/vY"
  },
  {
    "__type__": "cc.Node",
    "_name": "0",
    "_objFlags": 0,
    "_parent": {
      "__id__": 7
    },
    "_children": [],
    "_active": true,
    "_components": [],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 0,
      "height": 0
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        0,
        0,
        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": "5bIFmw2ctNMK2pw2eY+WU8"
  },
  {
    "__type__": "cc.Node",
    "_name": "New Button",
    "_objFlags": 0,
    "_parent": {
      "__id__": 2
    },
    "_children": [
      {
        "__id__": 10
      }
    ],
    "_active": true,
    "_components": [
      {
        "__id__": 15
      }
    ],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 100,
      "height": 40
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        -585.668,
        320.444,
        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": "d38WRetPZMX6AXGioWyXAw"
  },
  {
    "__type__": "cc.Node",
    "_name": "Background",
    "_objFlags": 512,
    "_parent": {
      "__id__": 9
    },
    "_children": [
      {
        "__id__": 11
      }
    ],
    "_active": true,
    "_components": [
      {
        "__id__": 13
      },
      {
        "__id__": 14
      }
    ],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 100,
      "height": 40
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        1,
        1,
        0
      ]
    },
    "_eulerAngles": {
      "__type__": "cc.Vec3",
      "x": 0,
      "y": 0,
      "z": 0
    },
    "_skewX": 0,
    "_skewY": 0,
    "_is3DNode": false,
    "_groupIndex": 0,
    "groupIndex": 0,
    "_id": "e0se/vJjFJeIPyDWG1bf8u"
  },
  {
    "__type__": "cc.Node",
    "_name": "Label",
    "_objFlags": 512,
    "_parent": {
      "__id__": 10
    },
    "_children": [],
    "_active": true,
    "_components": [
      {
        "__id__": 12
      }
    ],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 0,
      "g": 0,
      "b": 0,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 100,
      "height": 40
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        0,
        0,
        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": "791i0s6L9GzquUKnN2Sa+6"
  },
  {
    "__type__": "cc.Label",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 11
    },
    "_enabled": true,
    "_materials": [
      {
        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
      }
    ],
    "_srcBlendFactor": 770,
    "_dstBlendFactor": 771,
    "_string": "add a",
    "_N$string": "add a",
    "_fontSize": 20,
    "_lineHeight": 40,
    "_enableWrapText": false,
    "_N$file": null,
    "_isSystemFontUsed": true,
    "_spacingX": 0,
    "_batchAsBitmap": false,
    "_styleFlags": 0,
    "_underlineHeight": 0,
    "_N$horizontalAlign": 1,
    "_N$verticalAlign": 1,
    "_N$fontFamily": "Arial",
    "_N$overflow": 1,
    "_N$cacheMode": 1,
    "_id": "59uT08s2pJ1Ig83P8W9C5Q"
  },
  {
    "__type__": "cc.Sprite",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 10
    },
    "_enabled": true,
    "_materials": [
      {
        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
      }
    ],
    "_srcBlendFactor": 770,
    "_dstBlendFactor": 771,
    "_spriteFrame": {
      "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952"
    },
    "_type": 1,
    "_sizeMode": 0,
    "_fillType": 0,
    "_fillCenter": {
      "__type__": "cc.Vec2",
      "x": 0,
      "y": 0
    },
    "_fillStart": 0,
    "_fillRange": 0,
    "_isTrimmedMode": true,
    "_atlas": null,
    "_id": "9d6JOu/ppElbtVzk9cY55a"
  },
  {
    "__type__": "cc.Widget",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 10
    },
    "_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": 100,
    "_originalHeight": 40,
    "_id": "90P3ZcxP5OU4yDv1xMALiT"
  },
  {
    "__type__": "cc.Button",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 9
    },
    "_enabled": true,
    "_normalMaterial": null,
    "_grayMaterial": null,
    "duration": 0.1,
    "zoomScale": 1.2,
    "clickEvents": [
      {
        "__id__": 16
      }
    ],
    "_N$interactable": true,
    "_N$enableAutoGrayEffect": false,
    "_N$transition": 3,
    "transition": 3,
    "_N$normalColor": {
      "__type__": "cc.Color",
      "r": 230,
      "g": 230,
      "b": 230,
      "a": 255
    },
    "_N$pressedColor": {
      "__type__": "cc.Color",
      "r": 200,
      "g": 200,
      "b": 200,
      "a": 255
    },
    "pressedColor": {
      "__type__": "cc.Color",
      "r": 200,
      "g": 200,
      "b": 200,
      "a": 255
    },
    "_N$hoverColor": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "hoverColor": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_N$disabledColor": {
      "__type__": "cc.Color",
      "r": 120,
      "g": 120,
      "b": 120,
      "a": 200
    },
    "_N$normalSprite": {
      "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952"
    },
    "_N$pressedSprite": {
      "__uuid__": "e9ec654c-97a2-4787-9325-e6a10375219a"
    },
    "pressedSprite": {
      "__uuid__": "e9ec654c-97a2-4787-9325-e6a10375219a"
    },
    "_N$hoverSprite": {
      "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952"
    },
    "hoverSprite": {
      "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952"
    },
    "_N$disabledSprite": {
      "__uuid__": "29158224-f8dd-4661-a796-1ffab537140e"
    },
    "_N$target": {
      "__id__": 10
    },
    "_id": "d6HwYkhPdKppYL8wV8YIBf"
  },
  {
    "__type__": "cc.ClickEvent",
    "target": {
      "__id__": 2
    },
    "component": "",
    "_componentId": "e1b90/rohdEk4SdmmEZANaD",
    "handler": "onClick1",
    "customEventData": ""
  },
  {
    "__type__": "cc.Node",
    "_name": "New Button",
    "_objFlags": 0,
    "_parent": {
      "__id__": 2
    },
    "_children": [
      {
        "__id__": 18
      }
    ],
    "_active": true,
    "_components": [
      {
        "__id__": 23
      }
    ],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 100,
      "height": 40
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        -583.658,
        262.887,
        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": "02FO0vIuRMv5Heo4FvO4wf"
  },
  {
    "__type__": "cc.Node",
    "_name": "Background",
    "_objFlags": 512,
    "_parent": {
      "__id__": 17
    },
    "_children": [
      {
        "__id__": 19
      }
    ],
    "_active": true,
    "_components": [
      {
        "__id__": 21
      },
      {
        "__id__": 22
      }
    ],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 100,
      "height": 40
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        1,
        1,
        0
      ]
    },
    "_eulerAngles": {
      "__type__": "cc.Vec3",
      "x": 0,
      "y": 0,
      "z": 0
    },
    "_skewX": 0,
    "_skewY": 0,
    "_is3DNode": false,
    "_groupIndex": 0,
    "groupIndex": 0,
    "_id": "2a0VsIx4BHSoIBXHIYI5c3"
  },
  {
    "__type__": "cc.Node",
    "_name": "Label",
    "_objFlags": 512,
    "_parent": {
      "__id__": 18
    },
    "_children": [],
    "_active": true,
    "_components": [
      {
        "__id__": 20
      }
    ],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 0,
      "g": 0,
      "b": 0,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 100,
      "height": 40
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        0,
        0,
        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": "06UhOpZLBBeblPYUdQ9Iep"
  },
  {
    "__type__": "cc.Label",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 19
    },
    "_enabled": true,
    "_materials": [
      {
        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
      }
    ],
    "_srcBlendFactor": 770,
    "_dstBlendFactor": 771,
    "_string": "add b",
    "_N$string": "add b",
    "_fontSize": 20,
    "_lineHeight": 40,
    "_enableWrapText": false,
    "_N$file": null,
    "_isSystemFontUsed": true,
    "_spacingX": 0,
    "_batchAsBitmap": false,
    "_styleFlags": 0,
    "_underlineHeight": 0,
    "_N$horizontalAlign": 1,
    "_N$verticalAlign": 1,
    "_N$fontFamily": "Arial",
    "_N$overflow": 1,
    "_N$cacheMode": 1,
    "_id": "20/fyOiTtG7LZncWp69gKm"
  },
  {
    "__type__": "cc.Sprite",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 18
    },
    "_enabled": true,
    "_materials": [
      {
        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
      }
    ],
    "_srcBlendFactor": 770,
    "_dstBlendFactor": 771,
    "_spriteFrame": {
      "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952"
    },
    "_type": 1,
    "_sizeMode": 0,
    "_fillType": 0,
    "_fillCenter": {
      "__type__": "cc.Vec2",
      "x": 0,
      "y": 0
    },
    "_fillStart": 0,
    "_fillRange": 0,
    "_isTrimmedMode": true,
    "_atlas": null,
    "_id": "6bwBtEHoxKkYEgaOcLEuJR"
  },
  {
    "__type__": "cc.Widget",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 18
    },
    "_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": 100,
    "_originalHeight": 40,
    "_id": "44V2B73EROlbFy7IDnIgCH"
  },
  {
    "__type__": "cc.Button",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 17
    },
    "_enabled": true,
    "_normalMaterial": null,
    "_grayMaterial": null,
    "duration": 0.1,
    "zoomScale": 1.2,
    "clickEvents": [
      {
        "__id__": 24
      }
    ],
    "_N$interactable": true,
    "_N$enableAutoGrayEffect": false,
    "_N$transition": 3,
    "transition": 3,
    "_N$normalColor": {
      "__type__": "cc.Color",
      "r": 230,
      "g": 230,
      "b": 230,
      "a": 255
    },
    "_N$pressedColor": {
      "__type__": "cc.Color",
      "r": 200,
      "g": 200,
      "b": 200,
      "a": 255
    },
    "pressedColor": {
      "__type__": "cc.Color",
      "r": 200,
      "g": 200,
      "b": 200,
      "a": 255
    },
    "_N$hoverColor": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "hoverColor": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_N$disabledColor": {
      "__type__": "cc.Color",
      "r": 120,
      "g": 120,
      "b": 120,
      "a": 200
    },
    "_N$normalSprite": {
      "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952"
    },
    "_N$pressedSprite": {
      "__uuid__": "e9ec654c-97a2-4787-9325-e6a10375219a"
    },
    "pressedSprite": {
      "__uuid__": "e9ec654c-97a2-4787-9325-e6a10375219a"
    },
    "_N$hoverSprite": {
      "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952"
    },
    "hoverSprite": {
      "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952"
    },
    "_N$disabledSprite": {
      "__uuid__": "29158224-f8dd-4661-a796-1ffab537140e"
    },
    "_N$target": {
      "__id__": 18
    },
    "_id": "63e/kLBnZF/LA3UC/rFE7l"
  },
  {
    "__type__": "cc.ClickEvent",
    "target": {
      "__id__": 2
    },
    "component": "",
    "_componentId": "e1b90/rohdEk4SdmmEZANaD",
    "handler": "onClick2",
    "customEventData": ""
  },
  {
    "__type__": "cc.Node",
    "_name": "New Button",
    "_objFlags": 0,
    "_parent": {
      "__id__": 2
    },
    "_children": [
      {
        "__id__": 26
      }
    ],
    "_active": true,
    "_components": [
      {
        "__id__": 31
      }
    ],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 100,
      "height": 40
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        -582.95,
        205.33,
        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": "85qrRc4bZJc5jmPaLOoN5t"
  },
  {
    "__type__": "cc.Node",
    "_name": "Background",
    "_objFlags": 512,
    "_parent": {
      "__id__": 25
    },
    "_children": [
      {
        "__id__": 27
      }
    ],
    "_active": true,
    "_components": [
      {
        "__id__": 29
      },
      {
        "__id__": 30
      }
    ],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 100,
      "height": 40
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        1,
        1,
        0
      ]
    },
    "_eulerAngles": {
      "__type__": "cc.Vec3",
      "x": 0,
      "y": 0,
      "z": 0
    },
    "_skewX": 0,
    "_skewY": 0,
    "_is3DNode": false,
    "_groupIndex": 0,
    "groupIndex": 0,
    "_id": "0ekZoSTDRBLICbpC5YU3je"
  },
  {
    "__type__": "cc.Node",
    "_name": "Label",
    "_objFlags": 512,
    "_parent": {
      "__id__": 26
    },
    "_children": [],
    "_active": true,
    "_components": [
      {
        "__id__": 28
      }
    ],
    "_prefab": null,
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 0,
      "g": 0,
      "b": 0,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 100,
      "height": 40
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        0,
        0,
        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": "b1O0CAOdZBz5+5gIn3dR5n"
  },
  {
    "__type__": "cc.Label",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 27
    },
    "_enabled": true,
    "_materials": [
      {
        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
      }
    ],
    "_srcBlendFactor": 770,
    "_dstBlendFactor": 771,
    "_string": "debug",
    "_N$string": "debug",
    "_fontSize": 20,
    "_lineHeight": 40,
    "_enableWrapText": false,
    "_N$file": null,
    "_isSystemFontUsed": true,
    "_spacingX": 0,
    "_batchAsBitmap": false,
    "_styleFlags": 0,
    "_underlineHeight": 0,
    "_N$horizontalAlign": 1,
    "_N$verticalAlign": 1,
    "_N$fontFamily": "Arial",
    "_N$overflow": 1,
    "_N$cacheMode": 1,
    "_id": "6cPxNByvpCFJiTXSiCxOaC"
  },
  {
    "__type__": "cc.Sprite",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 26
    },
    "_enabled": true,
    "_materials": [
      {
        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
      }
    ],
    "_srcBlendFactor": 770,
    "_dstBlendFactor": 771,
    "_spriteFrame": {
      "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952"
    },
    "_type": 1,
    "_sizeMode": 0,
    "_fillType": 0,
    "_fillCenter": {
      "__type__": "cc.Vec2",
      "x": 0,
      "y": 0
    },
    "_fillStart": 0,
    "_fillRange": 0,
    "_isTrimmedMode": true,
    "_atlas": null,
    "_id": "adrDAfICJAQ4XbjieFeAUn"
  },
  {
    "__type__": "cc.Widget",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 26
    },
    "_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": 100,
    "_originalHeight": 40,
    "_id": "d4dYinX5hGWaxVDkLesoz7"
  },
  {
    "__type__": "cc.Button",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 25
    },
    "_enabled": true,
    "_normalMaterial": null,
    "_grayMaterial": null,
    "duration": 0.1,
    "zoomScale": 1.2,
    "clickEvents": [
      {
        "__id__": 32
      }
    ],
    "_N$interactable": true,
    "_N$enableAutoGrayEffect": false,
    "_N$transition": 3,
    "transition": 3,
    "_N$normalColor": {
      "__type__": "cc.Color",
      "r": 230,
      "g": 230,
      "b": 230,
      "a": 255
    },
    "_N$pressedColor": {
      "__type__": "cc.Color",
      "r": 200,
      "g": 200,
      "b": 200,
      "a": 255
    },
    "pressedColor": {
      "__type__": "cc.Color",
      "r": 200,
      "g": 200,
      "b": 200,
      "a": 255
    },
    "_N$hoverColor": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "hoverColor": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_N$disabledColor": {
      "__type__": "cc.Color",
      "r": 120,
      "g": 120,
      "b": 120,
      "a": 200
    },
    "_N$normalSprite": {
      "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952"
    },
    "_N$pressedSprite": {
      "__uuid__": "e9ec654c-97a2-4787-9325-e6a10375219a"
    },
    "pressedSprite": {
      "__uuid__": "e9ec654c-97a2-4787-9325-e6a10375219a"
    },
    "_N$hoverSprite": {
      "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952"
    },
    "hoverSprite": {
      "__uuid__": "f0048c10-f03e-4c97-b9d3-3506e1d58952"
    },
    "_N$disabledSprite": {
      "__uuid__": "29158224-f8dd-4661-a796-1ffab537140e"
    },
    "_N$target": {
      "__id__": 26
    },
    "_id": "749WE4zm1JhpiMAmdyMCeA"
  },
  {
    "__type__": "cc.ClickEvent",
    "target": {
      "__id__": 2
    },
    "component": "",
    "_componentId": "e1b90/rohdEk4SdmmEZANaD",
    "handler": "onClick3",
    "customEventData": ""
  },
  {
    "__type__": "cc.Canvas",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 2
    },
    "_enabled": true,
    "_designResolution": {
      "__type__": "cc.Size",
      "width": 1334,
      "height": 750
    },
    "_fitWidth": false,
    "_fitHeight": true,
    "_id": "b44LthhkFIWLEP6Fdfe0sY"
  },
  {
    "__type__": "e1b90/rohdEk4SdmmEZANaD",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 2
    },
    "_enabled": true,
    "_id": "8eaUVpWkdHbJTK8RmMCvdS"
  },
  {
    "__type__": "cc.Widget",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 2
    },
    "_enabled": true,
    "alignMode": 1,
    "_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": 0,
    "_originalHeight": 0,
    "_id": "58pIEnaLpGtp7OTXFMAGYF"
  }
]

================================================
FILE: assets/Scene/helloworld.fire.meta
================================================
{
  "ver": "1.3.2",
  "uuid": "2d2f792f-a40c-49bb-a189-ed176a246e49",
  "importer": "scene",
  "asyncLoadAssets": false,
  "autoReleaseAssets": false,
  "subMetas": {}
}

================================================
FILE: assets/Scene.meta
================================================
{
  "ver": "1.1.3",
  "uuid": "29f52784-2fca-467b-92e7-8fd9ef8c57b7",
  "importer": "folder",
  "isBundle": false,
  "bundleName": "",
  "priority": 1,
  "compressionType": {},
  "optimizeHotUpdate": {},
  "inlineSpriteFrames": {},
  "isRemoteBundle": {},
  "subMetas": {}
}

================================================
FILE: assets/Script/Common/BehaviorTree.ts
================================================
import { ComAttackable } from "../ECS/components/ComAttackable";
import { ComBeAttacked } from "../ECS/components/ComBeAttacked";
import { ComCocosNode } from "../ECS/components/ComCocosNode";
import { ComMonitor } from "../ECS/components/ComMonitor";
import { ComMovable } from "../ECS/components/ComMovable";
import { ComRoleConfig } from "../ECS/components/ComRoleConfig";
import { ComTransform } from "../ECS/components/ComTransform";
import { ECSWorld } from "../ECS/lib/ECSWorld";
import { SysBehaviorTree } from "../ECS/systems/SysBehaviorTree";
import { EventAttack, EventHPChange, EventHurt } from "../Struct/NodeEvent";
export namespace BT {

    export class BlackBoard {

    }
    
    export class ExecuteContext {
        executor: SysBehaviorTree;
        world: ECSWorld;
        bb: BlackBoard;

        entity: number;
        dt: number;
        public init(executor: SysBehaviorTree, world: ECSWorld) {
            this.executor = executor;
            this.world = world;
        }

        public set(entity: number, dt: number, bb: BlackBoard) {
            this.entity = entity;
            this.dt = dt;
            this.bb = bb;
        }
    }

    /** 节点状态 */
    export enum NodeState {
        Executing,                  // 执行中
        Success,                    // 成功
        Fail                        // 失败
    }


    /** 节点类型 */
    export enum NodeType {
        // 组合节点
        LockedSequence,             // 锁状态顺序节点
        Sequence,                   // 
        Selector,                   // 选择节点
        RandomSelector,             // 随机选择节点
        Parallel,                   // 并行节点

        // 修饰节点
        Inverter,                   // 逆变节点
        Success,                    // 成功节点
        Fail,                       // 失败节点
        Repeater,                   // 重复节点
        RetryTillSuccess,           // 重复直到成功

        // 叶子结点
        Wait,                       // 等待
        Action,
        WalkToPos,
        WalkToRandomPos,            // 
        WalkToTarget,
        Monitor,                     // 监视
        Attack,

        EnoughAttr,                 // 足够的属性
        WillBeAttacked,             // 即将收到攻击
        Avoid,                      // 闪避
        RunAway,                    // 逃跑          
        InAttacking    

    }

    export class NodeBase {
        public type: NodeType;
        public state: NodeState = NodeState.Success;

        constructor(type: NodeType) {
            this.type = type;
        }
    }

    /** 组合节点 */
    class CombineNode extends NodeBase {
        public children: NodeBase[] = [];

        public constructor(type: NodeType, children: NodeBase[]) {
            super(type);
            this.children = children;
        }
    }

    export class SequenceNode extends CombineNode {
        public currIdx = 0;
        public ignoreFailure = false;

        constructor(children: NodeBase[], ignoreFailture = false) {
            super(NodeType.Sequence, children);
            this.ignoreFailure = ignoreFailture;
        }
    }

    /** 依次执行子节点, 遇到执行失败的则退出并返回失败, 全部执行成功则返回成功  */
    export class LockedSequenceNode extends CombineNode {
        public currIdx = 0;
        public ignoreFailure = false;

        constructor(children: NodeBase[], ignoreFailture = false) {
            super(NodeType.LockedSequence, children);
            this.ignoreFailure = ignoreFailture;
        }
    }

    /** 依次执行子节点, 遇到执行成功的则退出并返回成功, 全部执行失败则返回失败 */
    export class SelectorNode extends CombineNode {
        public currIdx:number = -1;

        constructor(children: NodeBase[], ) {
            super(NodeType.Selector, children);
        }
    }

    /** 根据权重随机选择执行某个子节点 */
    export class RandomSelectorNode extends CombineNode {
        public weights: number[];       // 权重
        public currIdx = -1;            // 选中的节点
        constructor(children: NodeBase[], weigets?: number[]) {
            super(NodeType.RandomSelector, children);
            this.weights = weigets ? weigets : new Array(children.length).fill(1);
        }
    }
    
    /** 并行执行所有子节点, 全部执行完毕后返回 */
    export class ParallelNode extends CombineNode {
        public ignoreFailture = true;
        constructor(children: NodeBase[], ignoreFailture: boolean) {
            super(NodeType.Parallel, children);
            this.ignoreFailture = ignoreFailture;
        }
    }

    /** 修饰节点 */
    class DecoratorNode extends NodeBase {
        public child: NodeBase = null;
        public constructor(type: NodeType, child: NodeBase) {
            super(type);
            this.child = child;
        }
    }

    /** 返回子节点执行结果的取反值 */
    export class InverterNode extends DecoratorNode {
        constructor(child: NodeBase) {
            super(NodeType.Inverter, child);
        }
    }

    /** 子节点执行完毕后, 必定返回成功 */
    export class SuccessNode extends DecoratorNode {
        constructor(child: NodeBase) {
            super(NodeType.Success, child);
        }
    }

    /** 子节点执行完毕后, 必定返回失败 */
    export class FailNode extends DecoratorNode {
        constructor(child: NodeBase) {
            super(NodeType.Fail, child);
        }
    }

    /** 子节点执行重复repeatCount次后返回成功 */
    export class RepeaterNode extends DecoratorNode {
        public repeatCount = 1;
        public currRepeatCount = 0;
        public mustSuccess = false;     // 子节点必须支持成功才增加重复次数
        constructor(child: NodeBase, repeatCount: number, mustSuccess = false) {
            super(NodeType.Repeater, child);
            this.repeatCount = repeatCount;
            this.mustSuccess = mustSuccess;
        }
    }

    /** 子节点重复执行直到返回成功 */
    export class RetryTillSuccess extends DecoratorNode {
        timeout: number;    // 超时时间
        countDown: number;  // 剩余时间
        constructor(child: NodeBase, timeout:number) {
            super(NodeType.RetryTillSuccess, child);
            this.timeout = timeout;
        }
    }


    /** 叶子结点 */
    export class WaitNode extends NodeBase {
        public waitSeconds:number;
        public countDown:number;

        constructor(seconds:number) {
            super(NodeType.Wait);
            this.waitSeconds = seconds;
        }
    }

    /** 移动到目标位置后 返回成功 */
    export class WalkToPosNode extends NodeBase {
        public speed:number;
        public targetPos: cc.Vec2;
        constructor(speed: number, pos: cc.Vec2) {
            super(NodeType.WalkToPos);
            this.speed = speed;
            this.targetPos = pos;
        }
    }

    export class WalkToRandomPosNode extends NodeBase {
        public speed: number;
        public size: cc.Size;
        constructor(speed: number, size: cc.Size) {
            super(NodeType.WalkToRandomPos);
            this.speed = speed;
            this.size = size;
        }
    }

    export class WalkToTargetNode extends NodeBase {
        public speed: number;
        constructor(speed: number) {
            super(NodeType.WalkToTarget);
            this.speed = speed;
        }
    }

    export class MonitorNode extends NodeBase {
        constructor() {
            super(NodeType.Monitor);
        }
    }

    export class AttackNode extends NodeBase {
        constructor() {
            super(NodeType.Attack);
        }
    }

    export class EnoughAttrNode extends NodeBase {
        public com: {prototype: any};
        public attr: string;
        public value: number;
        constructor(com: {prototype: any}, attr: string, value: number) {
            super(NodeType.EnoughAttr);
            this.com = com;
            this.attr = attr;
            this.value = value;
        }
    }

    export class WillBeAttackedNode extends NodeBase {
        constructor() {
            super(NodeType.WillBeAttacked);
        }
    }

    export class AvoidNode extends NodeBase {
        public speed: number;
        constructor(speed: number) {
            super(NodeType.Avoid);
            this.speed = speed;
        }
    }

    export class RunAwayNode extends NodeBase {
        constructor() {
            super(NodeType.RunAway);
        }
    }

    export class InAttackingNode extends NodeBase {
        constructor() {
            super(NodeType.InAttacking);
        }
    }

    class NodeHandler {
        onEnter:(node: NodeBase, context: ExecuteContext) => void;
        onUpdate:(node: NodeBase, context: ExecuteContext) => void;
    }

    export const NodeHandlers : NodeHandler[] = [];

    /** Sequence node */
    NodeHandlers[NodeType.Sequence] = {
        onEnter(node: SequenceNode, context: ExecuteContext) : void {
            node.currIdx = 0;
            context.executor.onEnterBTNode(node.children[node.currIdx], context);
            node.state = NodeState.Executing;
        },
        onUpdate(node: SequenceNode, context: ExecuteContext) : void {
            
            if(node.currIdx < 0 || node.currIdx >= node.children.length) {
                // 越界了, 不应该发生, 直接认为是失败了
                node.state = NodeState.Fail;
                return;
            }

            // 检查前置条件是否满足
            for(let i=0; i<node.currIdx; i++) {
                context.executor.updateBTNode(node.children[i], context);
                if(node.children[i].state !== NodeState.Success) return;
            }

            context.executor.updateBTNode(node.children[node.currIdx], context);
            let state = node.children[node.currIdx].state;
            if(state == NodeState.Executing) return;

            if(state === NodeState.Fail && !node.ignoreFailure) {
                node.state = NodeState.Fail;
                return;
            }
            if(state === NodeState.Success && node.currIdx == node.children.length-1) {
                node.state = NodeState.Success;
                return ;
            }
            context.executor.onEnterBTNode(node.children[++node.currIdx], context);
        }
    };

    /** LockedSequence node */
    NodeHandlers[NodeType.LockedSequence] = {
        onEnter(node: LockedSequenceNode, context: ExecuteContext) : void {
            node.currIdx = 0;
            context.executor.onEnterBTNode(node.children[node.currIdx], context);
            node.state = NodeState.Executing;
        },
        onUpdate(node: LockedSequenceNode, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            if(node.currIdx < 0 || node.currIdx >= node.children.length) {
                // 越界了, 不应该发生, 直接认为是失败了
                node.state = NodeState.Fail;
                return;
            }

            context.executor.updateBTNode(node.children[node.currIdx], context);
            let state = node.children[node.currIdx].state;
            if(state == NodeState.Executing) return;

            if(state === NodeState.Fail && !node.ignoreFailure) {
                node.state = NodeState.Fail;
                return;
            }
            if(state === NodeState.Success && node.currIdx == node.children.length-1) {
                node.state = NodeState.Success;
                return ;
            }
            context.executor.onEnterBTNode(node.children[++node.currIdx], context);
        }
    };

    /** Selector node */
    NodeHandlers[NodeType.Selector] = {
        onEnter(node: SelectorNode, context: ExecuteContext) : void {
            node.currIdx = 0;
            context.executor.onEnterBTNode(node.children[node.currIdx], context);
            node.state = NodeState.Executing;
        },
        onUpdate(node: SelectorNode, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            if(node.currIdx < 0 || node.currIdx >= node.children.length) {
                // 越界了, 认为是失败了
                node.state = NodeState.Fail;
                return;
            }

            context.executor.updateBTNode(node.children[node.currIdx], context);
            let state = node.children[node.currIdx].state;
            if(state == NodeState.Executing) return;

            // 执行到最后一个都失败了, 那边selector失败了
            if(state === NodeState.Fail && node.currIdx == node.children.length-1) {
                node.state = NodeState.Fail;
                return;
            }
            if(state == NodeState.Success) {
                node.state = NodeState.Success;
                return ;
            }
            context.executor.onEnterBTNode(node.children[++node.currIdx], context);
        }
    };

    /** Selector node */
    NodeHandlers[NodeType.RandomSelector] = {
        onEnter(node: RandomSelectorNode, context: ExecuteContext) : void {
            // 根据权重随机获取idx
            let totalWeight = 0;
            for(const weight of node.weights) {
                totalWeight += weight;
            }
            let randomWeight = Math.random() * totalWeight;
            for(let i=0; i<node.weights.length; i++) {
                randomWeight -= node.weights[i];
                if(randomWeight <= 0) {
                    node.currIdx = i;
                    break;
                }
            }
            context.executor.onEnterBTNode(node.children[node.currIdx], context);
            node.state = NodeState.Executing;
        },
        onUpdate(node: RandomSelectorNode, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            let n = node.children[node.currIdx];
            context.executor.updateBTNode(n, context);
            node.state = n.state;
        }
    };

    /** Parallel node */
    NodeHandlers[NodeType.Parallel] = {
        onEnter(node: ParallelNode, context: ExecuteContext) : void {
            for(const n of node.children) {
                context.executor.onEnterBTNode(n, context);
            }
            node.state = NodeState.Executing;
        },
        onUpdate(node: ParallelNode, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            let end = true;
            for(const child of node.children) {
                context.executor.updateBTNode(child, context);
                if(child.state === NodeState.Executing) {
                    end = false;
                    continue;
                }

                if(child.state == NodeState.Fail) {
                    node.state = NodeState.Fail;
                    return ;
                }
            }
            if(end) {
                node.state = NodeState.Success;
            }
        }
    };

    /** Inverter node */
    NodeHandlers[NodeType.Inverter] = {
        onEnter(node: InverterNode, context: ExecuteContext) : void {
            context.executor.onEnterBTNode(node.child, context);
            node.state = NodeState.Executing;
        },
        onUpdate(node: InverterNode, context: ExecuteContext) : void {
            context.executor.updateBTNode(node.child, context);
            if(node.child.state === NodeState.Executing) return ;
            if(node.child.state == NodeState.Success) node.state = NodeState.Fail;
            if(node.child.state == NodeState.Fail) node.state = NodeState.Success;
        }
    };

    /** Success node */
    NodeHandlers[NodeType.Success] = {
        onEnter(node: SuccessNode, context: ExecuteContext) : void {
            context.executor.onEnterBTNode(node.child, context);
            node.state = NodeState.Executing;
        },
        onUpdate(node: SuccessNode, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            context.executor.updateBTNode(node.child, context);
            if(node.child.state === NodeState.Executing) return ;
            node.state = NodeState.Success;
        }
    };

    /** Fail node */
    NodeHandlers[NodeType.Fail] = {
        onEnter(node: FailNode, context: ExecuteContext) : void {
            context.executor.onEnterBTNode(node.child, context);
            node.state = NodeState.Executing;
        },
        onUpdate(node: FailNode, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            context.executor.updateBTNode(node.child, context);
            if(node.child.state === NodeState.Executing) return ;
            node.state = NodeState.Fail;
        }
    };

    /** Repeater node */
    NodeHandlers[NodeType.Repeater] = {
        onEnter(node: RepeaterNode, context: ExecuteContext) : void {
            node.currRepeatCount = 0;
            context.executor.onEnterBTNode(node.child, context);
            node.state = NodeState.Executing;
        },
        onUpdate(node: RepeaterNode, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            context.executor.updateBTNode(node.child, context);
            if(node.child.state === NodeState.Executing) return ;
            if(!node.mustSuccess || node.child.state == NodeState.Success) node.currRepeatCount ++;
            if(node.currRepeatCount >= node.repeatCount) {
                node.state = NodeState.Success;
                return ;
            }
            context.executor.onEnterBTNode(node.child, context);
        }
    };


    /** RetryTillSuccess node */
    NodeHandlers[NodeType.RetryTillSuccess] = {
        onEnter(node: RetryTillSuccess, context: ExecuteContext) : void {
            node.countDown = node.timeout;
            context.executor.onEnterBTNode(node.child, context);
            node.state = NodeState.Executing;
        },

        onUpdate(node: RetryTillSuccess, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            node.countDown -= context.dt;
            
            context.executor.updateBTNode(node.child, context);
            if(node.child.state === NodeState.Executing) return ;

            if(node.child.state == NodeState.Success) {
                node.state = NodeState.Success;
                return ;
            }

            if(node.countDown > 0) {
                context.executor.onEnterBTNode(node.child, context);
                return ;
            }
            node.state = NodeState.Fail;
        }
    };


    /** Wait node */
    NodeHandlers[NodeType.Wait] = {
        onEnter(node: WaitNode, context: ExecuteContext) : void {
            node.countDown = node.waitSeconds;
            node.state = NodeState.Executing;
        },
        onUpdate(node: WaitNode, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            node.countDown -= context.dt;
            if(node.countDown <= 0) {
                node.state = NodeState.Success;
            }
        }
    };

    /** Wait node */
    NodeHandlers[NodeType.WalkToPos] = {
        onEnter(node: WalkToPosNode, context: ExecuteContext) : void {
            let comTrans = context.world.getComponent(context.entity, ComTransform);
            let comMovable = context.world.getComponent(context.entity, ComMovable);
            comMovable.pointIdx = 0;
            comMovable.points.length = 0;
            comMovable.points.push(cc.v2(comTrans.x, comTrans.y), node.targetPos);
            comMovable.speed = node.speed;
            comMovable.speedDirty = true;
            comMovable.keepDir = false;
            node.state = NodeState.Executing;
            comMovable.running = false;
        },
        onUpdate(node: WalkToPosNode, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            let comMovable = context.world.getComponent(context.entity, ComMovable);
            if(comMovable.points.length == 0 || comMovable.pointIdx < 0 || comMovable.pointIdx >= comMovable.points.length) {
                node.state = BT.NodeState.Success;
            }
        }
    };

    /** WalkToRandomPos node */
    NodeHandlers[NodeType.WalkToRandomPos] = {
        onEnter(node: WalkToRandomPosNode, context: ExecuteContext) : void {
            let comTrans = context.world.getComponent(context.entity, ComTransform);
            let comMovable = context.world.getComponent(context.entity, ComMovable);
            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 - 150;
            comMovable.points.push(cc.v2(comTrans.x, comTrans.y), cc.v2(targetX, targetY));
            comMovable.speed = node.speed;
            comMovable.speedDirty = true;
            comMovable.keepDir = false;
            node.state = NodeState.Executing;
            comMovable.running = false;
        },
        onUpdate(node: WalkToPosNode, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            let comMovable = context.world.getComponent(context.entity, ComMovable);
            if(comMovable.points.length == 0 || comMovable.pointIdx < 0 || comMovable.pointIdx >= comMovable.points.length) {
                node.state = BT.NodeState.Success;
            }
        }
    };

    /** WalkToTarget node */
    NodeHandlers[NodeType.WalkToTarget] = {
        onEnter(node: WalkToTargetNode, context: ExecuteContext) : void {
            let comTrans = context.world.getComponent(context.entity, ComTransform);
            let comMovable = context.world.getComponent(context.entity, ComMovable);
            let comMonitor = context.world.getComponent(context.entity, ComMonitor);
            if(comMonitor.others.length <= 0) return ;
            let target = context.world.getComponent(comMonitor.others[0], ComTransform);
            let xOffdet = Math.sign(comTrans.x - target.x) * 80;
            comMovable.pointIdx = 0;
            comMovable.points.length = 0;
            comMovable.points.push(cc.v2(comTrans.x, comTrans.y), cc.v2(target.x + xOffdet, target.y));
            comMovable.speed = node.speed;
            comMovable.speedDirty = true;
            comMovable.keepDir = false;
            node.state = NodeState.Executing;
            comMovable.running = false;
            
        },
        onUpdate(node: WalkToTargetNode, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            let comTrans = context.world.getComponent(context.entity, ComTransform);
            let comMonitor = context.world.getComponent(context.entity, ComMonitor);
            let comMovable = context.world.getComponent(context.entity, ComMovable);
            if(comMonitor.others.length <=0){
                node.state = BT.NodeState.Fail;
                return ;
            }
            if(comMovable.points.length == 0 || comMovable.pointIdx < 0 || comMovable.pointIdx >= comMovable.points.length) {
                let target = context.world.getComponent(comMonitor.others[0], ComTransform);
        
                comTrans.dir.x = Math.abs(comTrans.dir.x) * -Math.sign(comTrans.x - target.x)
                node.state = BT.NodeState.Success;
                return ;
            }
            if(comMonitor.others.length <= 0) {
                node.state = BT.NodeState.Fail;
                return ;
            }
            let target = context.world.getComponent(comMonitor.others[0], ComTransform);
            let xOffdet = Math.sign(comTrans.x - target.x) * 80;
            comMovable.points[1].x = target.x + xOffdet;
            comMovable.points[1].y = target.y;
        }
    };

    /** Monitor node */
    NodeHandlers[NodeType.Monitor] = {
        onEnter(node: MonitorNode, context: ExecuteContext) : void {
            let comMonitor = context.world.getComponent(context.entity, ComMonitor);
            if(!comMonitor) return ;            
            node.state = NodeState.Executing;
        },
        onUpdate(node: MonitorNode, context: ExecuteContext) : void {
            let comMonitor = context.world.getComponent(context.entity, ComMonitor);
            node.state = comMonitor.others.length > 0 ? BT.NodeState.Success : BT.NodeState.Fail;
        }
    };

    /** Monitor node */
    NodeHandlers[NodeType.Attack] = {
        onEnter(node: AttackNode, context: ExecuteContext) : void {
            node.state = NodeState.Executing;
            
            let comCocosNode = context.world.getComponent(context.entity, ComCocosNode);
            if(!comCocosNode.loaded) return ;

            comCocosNode.events.push(new (EventAttack));
            let comAttackable = context.world.getComponent(context.entity, ComAttackable);
            comAttackable.countDown = comAttackable.duration;
            comAttackable.dirty = true;
            comAttackable.debugInfo = null;


            comAttackable.willHurtFrame = 0.8;
            comAttackable.willHurtFrameCompleted = false;

            comAttackable.hurtFrame = 0.5;
            comAttackable.hurtFrameCompleted = false;

            
        },
        onUpdate(node: AttackNode, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            let comAttackable = context.world.getComponent(context.entity, ComAttackable);
            
            if(comAttackable.countDown <= 0) {
                node.state = NodeState.Success;
            }
        }
    };

    /** EnoughAttr node */
    NodeHandlers[NodeType.EnoughAttr] = {
        onEnter(node: EnoughAttrNode, context: ExecuteContext) : void {
            let com = context.world.getComponent(context.entity, node.com);
            if(!com) return ;            
            node.state = NodeState.Executing;
        },
        onUpdate(node: EnoughAttrNode, context: ExecuteContext) : void {
            let com = context.world.getComponent(context.entity, node.com);
            if(!com) return ;            
            node.state = com[node.attr] >= node.value ? NodeState.Success : NodeState.Fail;
        }
    };

    /** WillBeAttacked node */
    NodeHandlers[NodeType.WillBeAttacked] = {
        onEnter(node: WillBeAttackedNode, context: ExecuteContext) : void {
            let comBeAttacked = context.world.getComponent(context.entity, ComBeAttacked);
            
            if(!comBeAttacked) return ;            
            node.state = NodeState.Executing;
        },
        onUpdate(node: WillBeAttackedNode, context: ExecuteContext) : void {
            let comBeAttacked = context.world.getComponent(context.entity, ComBeAttacked);
            let comMonitor = context.world.getComponent(context.entity, ComMonitor);
            let monitor = comMonitor.others && comMonitor.others.indexOf(comBeAttacked.attacker) !== -1;
            if(!comBeAttacked) return ;
            
            node.state = (monitor && comBeAttacked.attacker !== -1 && Math.random() > 0.8) ? NodeState.Success : NodeState.Fail;
        }
    };

    /** Avoid node */
    NodeHandlers[NodeType.Avoid] = {
        onEnter(node: AvoidNode, context: ExecuteContext) : void {
            let comTrans = context.world.getComponent(context.entity, ComTransform);
            let comMovable = context.world.getComponent(context.entity, ComMovable);
            comMovable.pointIdx = 0;
            comMovable.points.length = 0;

            let selfPoint = cc.v2(comTrans.x, comTrans.y);
            comMovable.points.push(selfPoint, selfPoint.sub(cc.v2(50 * Math.sign(comTrans.dir.x), 0)));
            comMovable.speed = node.speed;
            comMovable.speedDirty = true;
            comMovable.running = false;
            comMovable.keepDir = true;

            
            node.state = NodeState.Executing;
        },
        onUpdate(node: AvoidNode, context: ExecuteContext) : void {
            if(node.state !== NodeState.Executing) return ;
            let comMovable = context.world.getComponent(context.entity, ComMovable);
            if(!comMovable) {
                node.state = BT.NodeState.Fail;
                return ;
            }

            if(comMovable.points.length == 0 || comMovable.pointIdx < 0 || comMovable.pointIdx >= comMovable.points.length) {
                node.state = BT.NodeState.Success;
            }            
        }
    };

    /** NotInAttack node */
    NodeHandlers[NodeType.InAttacking] = {
        onEnter(node: InAttackingNode, context: ExecuteContext) : void {
            let comAttackable = context.world.getComponent(context.entity, ComAttackable);
            if(!comAttackable) return ;            
            node.state = NodeState.Executing;
        },
        onUpdate(node: InAttackingNode, context: ExecuteContext) : void {
            let comAttackable = context.world.getComponent(context.entity, ComAttackable);
            if(!comAttackable) return ;            

            node.state = (comAttackable.countDown > 0 && comAttackable.countDown < comAttackable.duration-0.2) ? NodeState.Success : NodeState.Fail;
        }
    };




}


================================================
FILE: assets/Script/Common/BehaviorTree.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "6cd218b5-3651-451d-90b5-5765b038f824",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/Common/CocosHelper.ts
================================================
export class LoadProgress {
    public url: string;
    public completedCount: number;
    public totalCount: number;
    public item: any;
    public cb?: Function;
}

/** 一些cocos api 的封装, promise函数统一加上sync后缀 */
export default class CocosHelper {

    public static async callInNextTick() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(true);
            }, 0);
        })
    }

    /** 加载进度 */
    public static loadProgress = new LoadProgress();

    /** 等待时间, 秒为单位 */
    public static sleepSync = function(dur: number): Promise<boolean> {
        return new Promise((resolve, reject) => {
            cc.Canvas.instance.scheduleOnce(() => {
                resolve(true);
            }, dur);
        });
    }

    /**
     * 
     * @param target 
     * @param repeat -1,表示永久执行
     * @param tweens 
     */
    public static async runRepeatTweenSync(target: any, repeat: number, ...tweens: cc.Tween[]) {
        return new Promise((resolve, reject) => {
            let selfTween = cc.tween(target);
            for(const tmpTween of tweens) {
                selfTween = selfTween.then(tmpTween);
            }
            if(repeat < 0) {
                cc.tween(target).repeatForever(selfTween).start();
            }else {
                cc.tween(target).repeat(repeat, selfTween).call(() => {
                    resolve(true);
                }).start();
            }
        });   
    }
    /** 同步的tween */
    public static async runTweenSync(target: any, ...tweens: cc.Tween[]): Promise<void> {
        return new Promise((resolve, reject) => {
            let selfTween = cc.tween(target);
            for(const tmpTween of tweens) {
                selfTween = selfTween.then(tmpTween);
            }
            selfTween.call(() => {
                resolve();
            }).start();
        });
    }
    /** 停止tween */
    public stopTween(target: any) {
        cc.Tween.stopAllByTarget(target);
    }
    public stopTweenByTag(tag: number) {
        cc.Tween.stopAllByTag(tag);
    }
    /** 同步的动作, 在2.4.x action已经被废弃了, 不建议使用 */
    public static async runActionSync(node: cc.Node, ...actions: cc.FiniteTimeAction[]) {
        if(!actions || actions.length <= 0) return ;
        return new Promise((resolve, reject) => {
            actions.push(cc.callFunc(() => {
                resolve(true);
            }));
            node.runAction(cc.sequence(actions));
        });
    }

    /** 同步的动画 */
    public static async runAnimSync(node: cc.Node, animName?: string | number) {
        let anim = node.getComponent(cc.Animation);
        if(!anim) return ;
        let clip: cc.AnimationClip = null;
        if(!animName) clip = anim.defaultClip;
        else {
            let clips = anim.getClips();
            if(typeof(animName) === "number") {
                clip = clips[animName];
            }else if(typeof(animName) === "string") {
                for(let i=0; i<clips.length; i++) {
                    if(clips[i].name === animName) {
                        clip = clips[i];
                        break;
                    }
                }
            }   
        }
        if(!clip) return ;
        await CocosHelper.sleepSync(clip.duration);
    }

    /** 加载资源异常时抛出错误 */
    public static loadResThrowErrorSync<T>(url: string, type: typeof cc.Asset, onProgress?: (completedCount: number, totalCount: number, item: any) => void): Promise<T> {    
        return null;
    }

    private static _loadingMap: {[key: string]: Function[]} = {};
    public static loadRes<T>(url: string, type: typeof cc.Asset, callback: Function ) {
        if(this._loadingMap[url]) {
            this._loadingMap[url].push(callback);
            return ;
        }
        this._loadingMap[url] = [callback];
        this.loadResSync<T>(url, type).then((data: any) => {
            let arr = this._loadingMap[url];
            for(const func of arr) {
                func(data);
            }
            this._loadingMap[url] = null;
            delete this._loadingMap[url];
        });
    }
    /** 加载资源 */
    public static loadResSync<T>(url: string, type: typeof cc.Asset, onProgress?: (completedCount: number, totalCount: number, item: any) => void): Promise<T>{
        return new Promise((resolve, reject) => {
            if(!onProgress) onProgress = this._onProgress;
            cc.resources.load(url, type, onProgress, (err, asset: any) => {
                if (err) {
                    cc.error(`${url} [资源加载] 错误 ${err}`);
                    resolve(null);
                }else {
                    resolve(asset);
                }
            });
        });
    }
    /** 
     * 加载进度
     * cb方法 其实目的是可以将loader方法的progress
     */
    private static _onProgress(completedCount: number, totalCount: number, item: any) {
        CocosHelper.loadProgress.completedCount = completedCount;
        CocosHelper.loadProgress.totalCount = totalCount;
        CocosHelper.loadProgress.item = item;
        CocosHelper.loadProgress.cb && CocosHelper.loadProgress.cb(completedCount, totalCount, item);
    }
    /**
     * 寻找子节点
     */
    public static findChildInNode(nodeName: string, rootNode: cc.Node): cc.Node {
        if(rootNode.name == nodeName) {
            return rootNode;
        }
        for(let i=0; i<rootNode.childrenCount; i++) {
            let node = this.findChildInNode(nodeName, rootNode.children[i]);
            if(node) {
                return node;
            }
        }
        return null;
    }

    /** 获得Component的类名 */
    public static getComponentName(com: Function) {
        let arr = com.name.match(/<.*>$/);
        if(arr && arr.length > 0) {
            return arr[0].slice(1, -1);
        }
        return com.name;
    }
    /** 加载bundle */
    public static loadBundleSync(url: string, options: any): Promise<cc.AssetManager.Bundle> {
        return new Promise((resolve, reject) => {
            cc.assetManager.loadBundle(url, options, (err: Error, bundle: cc.AssetManager.Bundle) => {
                if(!err) {
                    cc.error(`加载bundle失败, url: ${url}, err:${err}`);
                    resolve(null);
                }else {
                    resolve(bundle);
                }
            });
        });
    }
    
    /** 路径是相对分包文件夹路径的相对路径 */
    public static loadAssetFromBundleSync(bundleName: string, url: string) {
        let bundle = cc.assetManager.getBundle(bundleName);
        if(!bundle) {
            cc.error(`加载bundle中的资源失败, 未找到bundle, bundleUrl:${bundleName}`);
            return null;
        }
        return new Promise((resolve, reject) => {
            bundle.load(url, (err, asset: cc.Asset | cc.Asset[]) => {
                if(err) {
                    cc.error(`加载bundle中的资源失败, 未找到asset, url:${url}, err:${err}`);
                    resolve(null);
                }else {
                    resolve(asset);
                }
            });
        });
    }

    /** 通过路径加载资源, 如果这个资源在bundle内, 会先加载bundle, 在解开bundle获得对应的资源 */
    public static loadAssetSync(url: string) {
        return new Promise((resolve, reject) => {
            cc.resources.load(url, (err, assets: cc.Asset | cc.Asset[]) => {
                if(!err) {
                    cc.error(`加载asset失败, url:${url}, err: ${err}`);
                    resolve(null);
                }else {
                    this.addRef(assets);
                    resolve(assets);
                }
            });
        });
    }
    /** 释放资源 */
    public static releaseAsset(assets: cc.Asset | cc.Asset[]) {
        this.decRes(assets);
    }
    /** 增加引用计数 */
    private static addRef(assets: cc.Asset | cc.Asset[]) {
        if(assets instanceof Array) {
            for(const a of assets) {
                a.addRef();
            }
        }else {
            assets.addRef();
        }
    }
    /** 减少引用计数, 当引用计数减少到0时,会自动销毁 */
    private static decRes(assets: cc.Asset | cc.Asset[]) {
        if(assets instanceof Array) {
            for(const a of assets) {
                a.decRef();
            }
        }else {
            assets.decRef();
        }
    }

    /** 截图 */
    public static captureScreen(camera: cc.Camera, prop?: cc.Node | cc.Rect) {
        let newTexture = new cc.RenderTexture();
        let oldTexture = camera.targetTexture;
        let rect: cc.Rect = cc.rect(0, 0, cc.visibleRect.width, cc.visibleRect.height);
        if(prop) {
            if(prop instanceof cc.Node) {
                rect = prop.getBoundingBoxToWorld();
            }else {
                rect = prop;
            }
        }
        newTexture.initWithSize(cc.visibleRect.width, cc.visibleRect.height, cc.game['_renderContext'].STENCIL_INDEX8);
        camera.targetTexture = newTexture;
        camera.render();
        camera.targetTexture = oldTexture;
        
        let buffer = new ArrayBuffer(rect.width * rect.height * 4);
        let data = new Uint8Array(buffer);
        newTexture.readPixels(data, rect.x, rect.y, rect.width, rect.height);
        return data;
    }

    public static tweenFloat(from: number, to: number, duration: number, onUpdate: (t: number) => void, onComplete?: Function, autoStart: boolean = true) {
        let o: Record<string, number> = { _value: from };
        Object.defineProperty(o, 'value', {
            get: () => o._value,
            set: (v: number) => { o._value = v; onUpdate && onUpdate(o._value); },
        });
        let tween = cc.tween(o).to(duration, { value: to }).call(onComplete);
        if (autoStart) {
            tween.start();
        }
        return tween;
    }

    public static tweenVec2(from: cc.Vec2, to: cc.Vec2, duration: number, onUpdate: (t: cc.Vec2) => void, onComplete?: Function, autoStart: boolean = true) {
        let o: Record<string, cc.Vec2> = {_value: from};
        Object.defineProperty(o, 'value', {
            get: () => o._value,
            set: (v: cc.Vec2) => { o._value = v; onUpdate && onUpdate(o._value); },
        });
        let tween = cc.tween(o).to(duration, { value: to }).call(onComplete);
        if (autoStart) {
            tween.start();
        }
        return tween;
    }

}



================================================
FILE: assets/Script/Common/CocosHelper.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "dc730152-9513-4cfe-b6f9-8d6cfdfc0e23",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/Common/FrameAnimation.ts
================================================
const {ccclass, property} = cc._decorator;

@ccclass('FrameConfig')
class FrameConfig {
    @property(cc.Integer) frames: number = 0;       // 
    @property(cc.Integer) frameInterval = 1;        // 帧数

    offsetFrame = 0;                                // 偏移量
}

@ccclass
export default class FrameAnimation extends cc.Component {

    @property(cc.Sprite) sprite: cc.Sprite = null;
    @property(cc.SpriteAtlas) spriteAtlas: cc.SpriteAtlas = null;
    @property(FrameConfig) frameConfigs: FrameConfig[] = [];

    @property(cc.Boolean) playOnLoad = false;
    @property(cc.Boolean) loop = false;
    @property(cc.Integer) defaultConfig = 0;
    
    private _passInterval = 0;
    private _currFrame = 0;
    private _currFrameConfig: FrameConfig = null;
    private _playing = false;
    private _loop = false;
    private _callback: Function;

    start () {
        if(!this.sprite) this.sprite = this.getComponent(cc.Sprite);

        let offset = 0;
        for(const config of this.frameConfigs) {
            config.offsetFrame += offset;
            offset += config.frames;
        }

        this._loop = this.loop;

        if(this.playOnLoad) {
            this._currFrameConfig = this.frameConfigs[this.defaultConfig];
            this._playing = true;
        }
    }


    play(configIdx: number, loop: boolean, callback?: Function) {
        this._currFrameConfig = this.frameConfigs[configIdx];
        this._loop = loop;
        this._currFrame = 0;
        this._playing = true;
        this._callback = callback;
    }

    stop() {
        this._playing = false;
    }

    update (dt: number) {
        if(!this._playing) return ;

        this._passInterval ++;
        if(this._passInterval < this._currFrameConfig.frameInterval) return ;
        this._passInterval = 0;
        
        this.sprite.spriteFrame = this.spriteAtlas.getSpriteFrames()[this._currFrameConfig.offsetFrame + this._currFrame];
        this._currFrame ++;

        if(this._currFrame < this._currFrameConfig.frames) return ;

        if(this._loop) this._currFrame = 0;
        else {
            this._playing = false;
            this._callback && this._callback();
        }
    }
}


================================================
FILE: assets/Script/Common/FrameAnimation.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "60f21b10-95a9-4650-83ae-ff5522171c04",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/Common.meta
================================================
{
  "ver": "1.1.3",
  "uuid": "07d0024f-7d77-45fb-84e1-676ae4645108",
  "importer": "folder",
  "isBundle": false,
  "bundleName": "",
  "priority": 1,
  "compressionType": {},
  "optimizeHotUpdate": {},
  "inlineSpriteFrames": {},
  "isRemoteBundle": {},
  "subMetas": {}
}

================================================
FILE: assets/Script/Core/ECSController.ts
================================================
import { BT } from "../Common/BehaviorTree";
import { ComAttackable } from "../ECS/components/ComAttackable";
import { ComBeAttacked } from "../ECS/components/ComBeAttacked";
import { ComBehaviorTree } from "../ECS/components/ComBehaviorTree";
import { ComCocosNode } from "../ECS/components/ComCocosNode";
import { ComMonitor } from "../ECS/components/ComMonitor";
import { ComMovable } from "../ECS/components/ComMovable";
import { ComNodeConfig } from "../ECS/components/ComNodeConfig";
import { ComRoleConfig } from "../ECS/components/ComRoleConfig";
import { ComTransform } from "../ECS/components/ComTransform";
import { ECSWorld } from "../ECS/lib/ECSWorld";

export class ECSController<T extends ECSWorld> {
    public world: T;
    public createRoleEntity(name: string) {
        let entity = this.world.createEntity();
        
        // 添加nodeconfig
        let comMap = this.world.addComponent(entity, ComNodeConfig);
        comMap.id = 1;
        comMap.layer = 0;
        comMap.prefabUrl =  `${name}/${name}`;

        // 添加transform
        let comTrans = this.world.addComponent(entity, ComTransform);
        comTrans.x = 0;
        comTrans.y = 0;

        // 添加behavior tree
        let comBehavior = this.world.addComponent(entity, ComBehaviorTree);
        
        let view = cc.view.getVisibleSize();
        
        
        let root = new BT.RepeaterNode(
            new BT.SelectorNode([
                new BT.ParallelNode([
                    new BT.InverterNode(new BT.SequenceNode([
                        new BT.WillBeAttackedNode(),
                        new BT.InverterNode(new BT.InAttackingNode())
                    ])),
                    new BT.SelectorNode([
                        new BT.ParallelNode([
                            new BT.InverterNode(new BT.MonitorNode()),
                            new BT.LockedSequenceNode([
                                new BT.WaitNode(1.5),
                                new BT.WalkToRandomPosNode(100, cc.size(view.width - 100, view.height - 300)),
                            ])
                        ], true),
                        new BT.LockedSequenceNode([
                            new BT.WalkToTargetNode(250),
                            new BT.AttackNode(),
                            new BT.WaitNode(0.8)
                        ])
                    ])
                ], true),
                new BT.LockedSequenceNode([
                    new BT.AvoidNode(500),
                    new BT.WaitNode(1),
                ])
            ])    
        , 9999);
        
        comBehavior.root = root;

        let comMovable = this.world.addComponent(entity, ComMovable);
        comMovable.pointIdx = -1;
        comMovable.running = false;

        let comMonitor = this.world.addComponent(entity, ComMonitor);
        comMonitor.lookLen = 200;
        comMonitor.lookWidth = 160;
        comMonitor.outLen = 100;
        comMonitor.aroundLen = 0;

        let comRoleConfig = this.world.addComponent(entity, ComRoleConfig);
        comRoleConfig.maxHP = 100;
        comRoleConfig.lastHP = 100;
        comRoleConfig.nowHP = 100;
        comRoleConfig.attack = 10;
        comRoleConfig.team = name == 'Biker' ? 1 : 2;

        let comAttackable = this.world.addComponent(entity, ComAttackable);
        comAttackable.dirty = false;
        comAttackable.duration = 1.2;
        comAttackable.countDown = 0;
        comAttackable.hurtArea = cc.v2(90, 30);
        comAttackable.attack = 10;

        let comBeAttacked = this.world.addComponent(entity, ComBeAttacked);
        comBeAttacked.attacker = -1;
        

        return entity;
    }
}

================================================
FILE: assets/Script/Core/ECSController.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "f4905a62-50f2-4508-8932-c2446dc9ee16",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/Core/EventProcess.ts
================================================
import { EventBase } from "../Struct/NodeEvent";

const {ccclass, property} = cc._decorator;

@ccclass
export class EventProcess extends cc.Component {
    public onAttach(): void {

    }

    public onDetach(): void {

    }

    public processEvent(event: EventBase): void {

    }

    public sync(x: number, y: number, dir: cc.Vec2) {
    }
}


================================================
FILE: assets/Script/Core/EventProcess.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "421fe0f3-34ce-4d96-8ede-370f051cdb61",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/Core/RoleEventProcess.ts
================================================
import CocosHelper from "../Common/CocosHelper";
import { EventBase, EventDeath, EventGraphicsDraw, EventHPChange, EventType } from "../Struct/NodeEvent";
import { EventProcess } from "./EventProcess";

const {ccclass, property} = cc._decorator;

@ccclass
export default class RoleEventProcess extends EventProcess {

    @property(cc.Animation) anim: cc.Animation = null;

    private graphics: cc.Graphics = null;
    start () {
        this.graphics = this.getComponent(cc.Graphics);
    }

    onAttach(): void {

    }

    onDetach(): void {

    }

    processEvent(event: EventBase): void {
        let _reset = (name: string) => {
            this.anim.on(cc.Animation.EventType.FINISHED, () => {
                this.anim.play(name);
            }, this);
        }
        switch(event.type) {
            case EventType.Stand:
                this.anim.play('stand');
            break;
            case EventType.Run:
                this.anim.play('run');
            break;
            case EventType.Attack:
                if(Math.random() > 0.5) {
                    this.anim.play('punch');
                }else {
                    this.anim.play('attack');
                }
                
                _reset('stand');
            break;
            case EventType.Hurt:
                this.anim.play('hurt');
                _reset('stand');
            break;
            case EventType.Death:
                this.anim.play('death');
                this.anim.on(cc.Animation.EventType.FINISHED, () => {
                    (event as EventDeath).callback();
                }, this);
            break;
            case EventType.HPChange:
                this._changeHP(event as EventHPChange);
            break;

            case EventType.GraphicsDraw:
                if(cc.debug.isDisplayStats()) {
                    console.log('=====')
                    this._graphicsDraw(event as EventGraphicsDraw);
                }else {
                    this._graphicsDraw(null);
                }
                 
            break;


        }
    }

    private _changeHP(event: EventHPChange) {
        let progressBar = this.node.getChildByName("HP").getComponent(cc.ProgressBar);
        let from = event.lastHP / event.maxHP;
        let to = event.nowHP / event.maxHP;
        CocosHelper.tweenFloat(from, to, 0.2, (v) => {
            progressBar.progress = v;
        });
    }

    private _graphicsDraw(event: EventGraphicsDraw) {
        if(!event || event.points.length <= 0) {
            this.graphics.clear();
            return ;
        }
        
        for(const p of event.points) {
            p.subSelf(this.node.getPosition());
        }

        this.graphics.strokeColor = event.color;
        this.graphics.moveTo(event.points[0].x, event.points[0].y);
        for(let i=1; i<event.points.length; i++) {
            this.graphics.lineTo(event.points[i].x, event.points[i].y);
        }
        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) {
        this.node.x = x;
        this.node.y = y;
        this.node.getChildByName('sp').scaleX = dir.x >= 0 ? 3 : -3;
        //this.node.getChildByName('HP').x = dir.x >= 0 ? -30 : 30;
    }

    // update (dt) {}
}


================================================
FILE: assets/Script/Core/RoleEventProcess.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "d38f8101-a4d4-422a-95ce-643759bfe803",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/Core.meta
================================================
{
  "ver": "1.1.3",
  "uuid": "5e76ac49-9cf7-4eba-9b00-da0cbbdf8778",
  "importer": "folder",
  "isBundle": false,
  "bundleName": "",
  "priority": 1,
  "compressionType": {},
  "optimizeHotUpdate": {},
  "inlineSpriteFrames": {},
  "isRemoteBundle": {},
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/components/ComAttackable.ts
================================================
import { ComType, EntityIndex } from "../lib/Const";
import { ECSComponent } from "../lib/ECSComponent";

@ECSComponent(ComType.ComAttackable)
export class ComAttackable {
    public duration: number;            // 攻击持续时间
    public countDown: number;           // 攻击剩余时间
    public dirty: boolean;              // 

    public willHurtFrame: number;               // 即将攻击
    public willHurtFrameCompleted: boolean;      // 即将攻击完成

    public hurtFrame: number;                   // 攻击
    public hurtFrameCompleted: boolean;         // 攻击完成
    
    
    public attack: number;              // 攻击力
    public hurtArea: cc.Vec2;           // 攻击区域

    public debugInfo: any;

    public willHurts: number[] = [];
}

================================================
FILE: assets/Script/ECS/components/ComAttackable.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "7ee555b4-eed0-4207-81f5-41b51bb3bd73",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/components/ComBeAttacked.ts
================================================
import { ComType, EntityIndex } from "../lib/Const";
import { ECSComponent } from "../lib/ECSComponent";

@ECSComponent(ComType.ComBeAttacked)
export class ComBeAttacked {
    public attacker: EntityIndex = -1;
}

================================================
FILE: assets/Script/ECS/components/ComBeAttacked.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "c3d913ea-e619-4f5e-bb18-3fe947505dda",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/components/ComBehaviorTree.ts
================================================
import { BT } from "../../Common/BehaviorTree";
import { ComType } from "../lib/Const";
import { ECSComponent } from "../lib/ECSComponent";

@ECSComponent(ComType.ComBehaviorTree)
export class ComBehaviorTree {
    public root: BT.NodeBase = null;
    public bb: BT.BlackBoard = new BT.BlackBoard();
}

================================================
FILE: assets/Script/ECS/components/ComBehaviorTree.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "a529fff3-0126-4e53-a4c7-e5ddb6d76976",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/components/ComCocosNode.ts
================================================
import { EventBase } from "../../Struct/NodeEvent";
import { ComType } from "../lib/Const";
import { ECSComponent } from "../lib/ECSComponent";

@ECSComponent(ComType.ComCocosNode)
export class ComCocosNode {
    public node: cc.Node = null;
    public loaded = false;
    public events: EventBase[] = [];
}

================================================
FILE: assets/Script/ECS/components/ComCocosNode.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "e75ab1ce-3260-45cb-975a-9c4c1ab72f94",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/components/ComMonitor.ts
================================================
import { ComType, EntityIndex } from "../lib/Const";
import { ECSComponent } from "../lib/ECSComponent";

@ECSComponent(ComType.ComMonitor)
export class ComMonitor {
    public lookLen = 0;
    public lookWidth = 0;
    public outLen = 0;
    public aroundLen = 0;
    public others: EntityIndex[] = [];
    public debugInfo: any;
}

================================================
FILE: assets/Script/ECS/components/ComMonitor.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "274fabed-397f-4950-b691-2c6b6b894c9f",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/components/ComMovable.ts
================================================
import { ComType } from "../lib/Const";
import { ECSComponent } from "../lib/ECSComponent";

@ECSComponent(ComType.ComMovable)
export class ComMovable {
    public running = false;
    public speed = 0;
    public points: cc.Vec2[] = [];
    public pointIdx = 0;
    public keepDir = false;
    public speedDirty = false;
}

================================================
FILE: assets/Script/ECS/components/ComMovable.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "773fd91d-89d6-499e-9488-3d85f11938a1",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/components/ComNodeConfig.ts
================================================
import { ComType } from "../lib/Const";
import { ECSComponent } from "../lib/ECSComponent";

@ECSComponent(ComType.ComNodeConfig)
export class ComNodeConfig {
    id = 0;                 // 唯一标识
    prefabUrl = '' 
    layer = 0;              // 层级
}

================================================
FILE: assets/Script/ECS/components/ComNodeConfig.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "ef2ff8f3-8ffa-49f6-8e55-b8ba0284a095",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/components/ComRoleConfig.ts
================================================
import { ComType } from "../lib/Const";
import { ECSComponent } from "../lib/ECSComponent";


@ECSComponent(ComType.ComRoleConfig)
export class ComRoleConfig {
    public team: number;
    public maxHP: number;
    public lastHP: number;
    public nowHP: number;
    public HPDirty: boolean;

    public attack: number;
    
    public moveSpeed: number;
}

================================================
FILE: assets/Script/ECS/components/ComRoleConfig.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "a0036aea-32a4-4b9b-a587-5262ea4cedf7",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/components/ComTransform.ts
================================================
import { ComType } from "../lib/Const";
import { ECSComponent } from "../lib/ECSComponent";

@ECSComponent(ComType.ComTransform)
export class ComTransform {
    public dir = cc.v2(1, 0);   //方向向量
    public x = 0;
    public y = 0;
    public width = 0;
    public height = 0;
}

================================================
FILE: assets/Script/ECS/components/ComTransform.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "0bb2991a-84c5-4b22-ade6-59d2e7e97252",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/components.meta
================================================
{
  "ver": "1.1.3",
  "uuid": "3878b852-fe53-405d-a5bf-3978aedd9ce7",
  "importer": "folder",
  "isBundle": false,
  "bundleName": "",
  "priority": 1,
  "compressionType": {},
  "optimizeHotUpdate": {},
  "inlineSpriteFrames": {},
  "isRemoteBundle": {},
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/lib/Const.ts
================================================

export type EntityIndex = number;

export type ComPoolIndex = number;

export enum ComType {
    ComCocosNode = 0,
    ComMovable = 1,
    ComNodeConfig = 2,
    ComBehaviorTree = 3,
    ComTransform = 4,
    ComMonitor = 5,
    ComRoleConfig = 6,
    ComAttackable = 7,
    ComBeAttacked = 8
}

================================================
FILE: assets/Script/ECS/lib/Const.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "ce38ec2f-50f5-4f7a-ad24-48a576032322",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/lib/ECSComponent.ts
================================================
import { ComType, EntityIndex } from "./Const";

/** 构造函数 */
export interface ECSComConstructor extends Function {
    new(): any;
}

export interface ECSTypedComConstructor<T> extends ECSComConstructor {
    new():T;
}

/** 通过type存取 构造函数 */
const ComConsMap: {[key: number]: ECSComConstructor} = cc.js.createMap();
function RegistComConstructor(comType: ComType, func: ECSComConstructor) {
    ComConsMap[comType] = func;
}
export function GetComConstructor(comType: ComType) {
    return ComConsMap[comType];
}

/** 通过构造函数存取 type */
function SetComConstructorType(comCons: ECSComConstructor, type: ComType) {
    comCons['__type__'] = type;
}
export function GetComConstructorType<T>(comCons: {prototype: T}): ComType {
    return comCons['__type__'];
}

/** ECSComponent */
export function ECSComponent(type: ComType) {
    return function(func: ECSComConstructor) {
        SetComConstructorType(func, type);
        RegistComConstructor(type, func);
    };
}



================================================
FILE: assets/Script/ECS/lib/ECSComponent.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "58b062eb-ce1e-49dd-8520-15713b92a51f",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/lib/ECSComponentPool.ts
================================================
import { ComPoolIndex } from "./Const";
import { ECSTypedComConstructor } from "./ECSComponent";

/**
 * 组件池
 */
export class ECSComponentPool<T> {
    private _componentConstructor: ECSTypedComConstructor<T>;
    public constructor(comCons: ECSTypedComConstructor<T>) {
        this._componentConstructor = comCons;
    }

    private _components: T[] = [];                              // components
    private _reservedIdxs: ComPoolIndex[] = [];                 // 缓存的component idx
    
    
    public get(idx: ComPoolIndex): T {
        return this._components[idx];
    }

    public alloc(): ComPoolIndex {
        if(this._reservedIdxs.length > 0) {
            let ret = this._reservedIdxs.pop();
            this._componentConstructor.apply(this._components[ret]);         // 重置对象
            return ret;
        }
        let newInstance = new this._componentConstructor();
        this._components.push(newInstance);
        return this._components.length - 1;
    }

    public free(idx: ComPoolIndex) {
        this._reservedIdxs.push(idx);
    }
}

================================================
FILE: assets/Script/ECS/lib/ECSComponentPool.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "a40c60fb-7834-4de4-b1e9-6a346dd68e60",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/lib/ECSFilter.ts
================================================
import { ComType, EntityIndex } from "./Const";
import { ECSWorld } from "./ECSWorld";

export class ECSFilter {
    private _world: ECSWorld = null;

    private _entitiesMap = new Map<EntityIndex, boolean>();

    private _acceptComTypes: ComType[] = [];        // 接收的组件类型
    private _rejectComTypes: ComType[] = [];        // 拒绝的组件类型

    public constructor(world: ECSWorld, accepts?: ComType[], rejects?: ComType[]) {
        this._world = world;
        this._acceptComTypes = accepts && accepts.length > 0 ? accepts : this._acceptComTypes;
        this._rejectComTypes = rejects && rejects.length > 0 ? rejects : this._rejectComTypes;
    }

    public get entities() {
        return this._entitiesMap;
    }

    public onEntityEnter(entity: EntityIndex) {
        if(this._entitiesMap.has(entity)) {
            console.warn(`[ECSFilter]: addEntity entity is had ${entity}`);
            return true;
        }
        this._entitiesMap.set(entity, true);
        return true;
    }

    public onEntityLeave(entity: EntityIndex) {
        if(!this._entitiesMap.has(entity)) {
            console.warn(`[ECSFilter]: removeEntity entity not had ${entity}`);
            return true;
        }
        this._entitiesMap.delete(entity);
    }

    public walk(callback?: (entity: number) => boolean) {
        this._entitiesMap.forEach((value, entity) => {
            callback(entity);
        });
    }

    public isAccept(entityIndex: EntityIndex) {
        for(let i = 0; i < this._acceptComTypes.length; i++) {
            if(this._world.getComponentPoolIdx(entityIndex, this._acceptComTypes[i]) == -1) {
                return false;
            }
        }
        for(let i = 0; i < this._rejectComTypes.length; i++) {
            if(this._world.getComponentPoolIdx(entityIndex, this._rejectComTypes[i]) != -1) {
                return false;
            }
        }
        return true;
    }

    public isContains(entity: number) {
        return this._entitiesMap.has(entity);
    }

    


}

================================================
FILE: assets/Script/ECS/lib/ECSFilter.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "9d20cc25-61b9-4be8-9e89-47bdcac35a5b",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/lib/ECSSystem.ts
================================================
import { ECSWorld } from "./ECSWorld";

export abstract class ECSSystem {
    /** 连接 */
    public abstract onAdd(world: ECSWorld): void;
    /** 断开连接 */
    public abstract onRemove(world: ECSWorld): void;
    /** 添加实体 */
    public abstract onEntityEnter(world: ECSWorld, entity: number): void;
    /**  */
    public abstract onEntityLeave(world: ECSWorld, entity: number): void;
    /** 更新 */
    public abstract onUpdate(world: ECSWorld, dt: number): void;
}

================================================
FILE: assets/Script/ECS/lib/ECSSystem.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "925b6e67-1234-4933-a867-339843b9a663",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/lib/ECSWorld.ts
================================================
import { ECSFilter } from "./ECSFilter"
import { ECSComConstructor, GetComConstructor as GetComConstructor, GetComConstructorType } from "./ECSComponent";
import { ECSSystem } from "./ECSSystem";
import { ComPoolIndex, ComType, EntityIndex } from "./Const";
import { ECSComponentPool } from "./ECSComponentPool";


export class ECSWorld {
    private _systems: ECSSystem[] = [];                         // world内所有的system
    private _entityIdxPools: number[] = [];                     // 回收entity
    private _entityToComponents: number[][] = [];               // entity component 二维表
    private _entitiesToDelete: Set<EntityIndex> = new Set();    // 统一删除entity
    private _componentPools: ECSComponentPool<any>[] = [];      // component pools
    private _filters = new Map<string, ECSFilter>();          // filter
    
    /** 获取ComponentPool */
    public getComponentPool<T>(typeOrFunc: ComType | {prototype: T}): ECSComponentPool<T> {
        let type = typeof typeOrFunc == "number" ? typeOrFunc : GetComConstructorType(typeOrFunc);
        if(!this._componentPools[type]) {
            this._componentPools[type] = new ECSComponentPool<T>(GetComConstructor(type));
        }
        return this._componentPools[type] as any;
    }

    /** 添加system */
    public addSystem(system: ECSSystem) {
        this._systems.push(system);
        system.onAdd(this);
        for(let i = 0; i < this._entityToComponents.length; i++) {
            system.onEntityEnter(this, i);
        }
    }

    /** 移除system */
    public removeSystem(system: ECSSystem) {
        system.onRemove(this);
        for(let i = 0; i < this._entityToComponents.length; i++) {
            system.onEntityLeave(this, i);
        }
        for(let i = this._systems.length - 1; i >= 0; i--) {
            if(this._systems[i] == system) {
                this._systems.splice(i, 1);
            }
        }
    }

    /** 创建实体 */
    public createEntity(): number {
        let index = -1;
        if(this._entityIdxPools.length > 0) {
            index = this._entityIdxPools.pop();
            this._entityToComponents[index].fill(-1);
        }else {
            index = this._entityToComponents.length;
            this._entityToComponents[index] = new Array<ComPoolIndex>(Object.keys(ComType).length/2).fill(-1);
        }
        for(let system of this._systems) {
            system.onEntityEnter(this, index);
        }
        return index;
    }

    /** 移除实体 */
    public removeEntity(entityIndex: EntityIndex): boolean {
        if(entityIndex <= 0) return false;
        if(!this._entityToComponents[entityIndex]) {
            console.warn(`[ECSWorld] removeEntity entity is removed`);
            return false;
        }

        this._filters.forEach((fillter, key) => {
            fillter.isContains(entityIndex) && fillter.onEntityLeave(entityIndex);
        });
        for(let system of this._systems) {
            system.onEntityLeave(this, entityIndex);
        }

        this._entitiesToDelete.add(entityIndex);
        return true;
    }

    public getComponentPoolIdx<T>(entityIndex: EntityIndex, com: {prototype: T} | ComType): ComPoolIndex {
        let entity = this._entityToComponents[entityIndex];
        if(!entity) return -1;
        let type = typeof com == 'number' ? com : GetComConstructorType(com);
        return entity[type];
    }

    public getComponent<T>(entityIndex: EntityIndex, com: {prototype: T} | ComType) {
        let comPoolIdx = this.getComponentPoolIdx(entityIndex, com);
        if(comPoolIdx == -1) return null;
        return this.getComponentPool<T>(com).get(comPoolIdx);
    }

    public addComponent<T>(entityIndex: EntityIndex, com: {prototype: T}, dirty = true) {
        let entity = this._entityToComponents[entityIndex];
        if(!entity) return null;
        let type = GetComConstructorType(com);
        let comPoolIdx = entity[type];
        if(comPoolIdx == -1) {
            comPoolIdx = this.getComponentPool<T>(com).alloc();    
        }
        entity[type] = comPoolIdx;
        dirty && this.setEntityDirty(entityIndex);
        return this.getComponentPool<T>(com).get(comPoolIdx)
    }

    public removeComponent(entityIndex: EntityIndex, com: ECSComConstructor, dirty = true) {
        let entity = this._entityToComponents[entityIndex];
        if(!entity) return true;
        let type = GetComConstructorType(com);
        let comPoolIdx = entity[type];
        if(comPoolIdx == -1) return true;
        entity[type] = -1;
        this.getComponentPool(com).free(comPoolIdx);
        dirty && this.setEntityDirty(entityIndex);
        return true;
    }

    public removeAllComponents(entityIndex: EntityIndex, dirty = true) {
        let entity = this._entityToComponents[entityIndex];
        if(!entity) return null;
        for(let i=0; i<entity.length; i++) {
            if(entity[i] == -1) continue;
            this.getComponentPool(i).free(entity[i]);
            entity[i] = -1;
        }
        dirty && this.setEntityDirty(entityIndex);
    }

    public getSingletonComponent<T>(com: {prototype: T}): T {
        let component = this.getComponent(0, com);
        if(!component) {
            component = this.addComponent(0, com);
        }
        return component;
    }

    public setEntityDirty(entityIndex: EntityIndex): void {
        this._filters.forEach((fillter, key) => {
            let accept = !this._entitiesToDelete.has(entityIndex) && fillter.isAccept(entityIndex);
            if(accept != fillter.isContains(entityIndex)) {
                accept ? fillter.onEntityEnter(entityIndex) : fillter.onEntityLeave(entityIndex);
            }
        });
    }


    public getFilter(fillterKey: string): ECSFilter {
        if(this._filters.has(fillterKey)) {
            return this._filters.get(fillterKey);
        }
        let [acceptStr, rejectStr] = fillterKey.split("-");
        let accept = acceptStr && acceptStr.length > 0 ? acceptStr.split(',').map(Number) : null;
        let reject = rejectStr && rejectStr.length > 0 ? rejectStr.split(',').map(Number) : null;
        let fillter = new ECSFilter(this, accept, reject);
        this._filters.set(fillterKey, fillter);
        // 将当期的entity放入fillter
        for(let i=1; i<this._entityToComponents.length; i++) {
            if(fillter.isAccept(i)) {
                fillter.onEntityEnter(i);
            }
        }
        return fillter;
    }

    public update(dt:number) {
        for(let system of this._systems) {
            system.onUpdate(this, dt);
        }
        if(this._entitiesToDelete.size > 0) {
            this._realRemoveEntity();
        }
    }

    private _realRemoveEntity() {
        this._entitiesToDelete.forEach((value) => {
            this.removeAllComponents(value);
            this._entityIdxPools.push(value);
        });
        this._entitiesToDelete.clear();
    }
}

export function GenFillterKey(accepts: ECSComConstructor[], rejects?: ECSComConstructor[]) {
    let acceptTypes: ComType[] = [];
    let rejectTypes: ComType[] = [];

    if(accepts && accepts.length > 0) {
        for(let i = 0; i < accepts.length; i++) {
            acceptTypes[i] = GetComConstructorType(accepts[i]);
        }
    }
    if(rejects && rejects.length > 0) {
        for(let i = 0; i < rejects.length; i++) {
            rejectTypes[i] = GetComConstructorType(rejects[i]);
        }
    }

    if(acceptTypes.length < 0) {
        console.error(`[ECSWorld]: GenFillterKey 必须要有accpters`);
        return "";
    }

    acceptTypes.sort();
    rejectTypes.sort();

    let key = Array.prototype.join.call(acceptTypes, ",");
    if(!rejectTypes || rejectTypes.length <= 0) return key;
    key += '-';
    key += Array.prototype.join.call(rejectTypes, ",");
    return key;
}


================================================
FILE: assets/Script/ECS/lib/ECSWorld.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "decf2eee-3ef7-456d-bd8c-8d4eaa63e617",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/lib.meta
================================================
{
  "ver": "1.1.3",
  "uuid": "fa6ac7d5-2bad-42ee-90ba-44147985428d",
  "importer": "folder",
  "isBundle": false,
  "bundleName": "",
  "priority": 1,
  "compressionType": {},
  "optimizeHotUpdate": {},
  "inlineSpriteFrames": {},
  "isRemoteBundle": {},
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/systems/SysAttack.ts
================================================
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([ComTransform, ComAttackable, ComRoleConfig]);
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.debugInfo = null;

            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
            }

            

            // 即将攻击未完成, 并且处于即将攻击时间段
            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;
                })
            }
            
            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;
                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;
        });
    }
}

================================================
FILE: assets/Script/ECS/systems/SysAttack.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "780c245c-45f2-47ae-a01a-b61dcfb3ab3e",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/systems/SysBehaviorTree.ts
================================================
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;
    }
}

================================================
FILE: assets/Script/ECS/systems/SysBehaviorTree.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "1b6bd6b5-cb8e-46e8-8052-8ed53e75a2e5",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/systems/SysCocosView.ts
================================================
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;
    }

    onTouchMove(worldPos: cc.Vec2, world: ECSWorld): void {
        
    }

    onTouchCancel(worldPos: cc.Vec2, world: ECSWorld): void {
        
    }

    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',comNodeConfig.prefabUrl);
            });
            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;
        });
        let layer = cc.find('Canvas/Layers/0');
        let count1 = 0, count2 = 0;
        for(const node of layer.children) {
            node.zIndex =  node.y * -1;
            if(node.name == 'Biker') count1++;
            if(node.name == 'Cyborg') count2++;
        }
        cc.find('Canvas/a_role_count').getComponent(cc.Label).string = '' + count1;
        cc.find('Canvas/b_role_count').getComponent(cc.Label).string = '' + count2;
    }


    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();
    }
}

================================================
FILE: assets/Script/ECS/systems/SysCocosView.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "e4f95950-b571-48dd-8c95-7808eef0c336",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/systems/SysMonitor.ts
================================================
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);

            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 _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) || isInTriangle(cc.v2(com.x, com.y), b, c, d))
                }

                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); 
}

================================================
FILE: assets/Script/ECS/systems/SysMonitor.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "0b207deb-ff30-4fbe-aca7-2f77f299569d",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/systems/SysMovable.ts
================================================
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;
                }
                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;
            }

            if(comMovable.pointIdx >= comMovable.points.length) {
                comMovable.speed = 0;
                comMovable.speedDirty = true;
            }

            return false;
        });
    }
}

================================================
FILE: assets/Script/ECS/systems/SysMovable.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "6f024564-9b8c-47ad-95eb-eca4afd96720",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/systems/SysRoleState.ts
================================================
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";
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);
            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;
                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;
        });
    }
}

================================================
FILE: assets/Script/ECS/systems/SysRoleState.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "b679be6f-54ac-4790-99ff-41e3993bf130",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/systems.meta
================================================
{
  "ver": "1.1.3",
  "uuid": "db93b255-0e1f-4c8a-adc8-d3d2fca077cc",
  "importer": "folder",
  "isBundle": false,
  "bundleName": "",
  "priority": 1,
  "compressionType": {},
  "optimizeHotUpdate": {},
  "inlineSpriteFrames": {},
  "isRemoteBundle": {},
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/worlds/WorldCocosView.ts
================================================
import { ECSWorld } from "../lib/ECSWorld";

export class WorldCocosView extends ECSWorld {
    
}

================================================
FILE: assets/Script/ECS/worlds/WorldCocosView.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "2bbeb931-7f40-48e4-937d-13006b7f016b",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS/worlds.meta
================================================
{
  "ver": "1.1.3",
  "uuid": "00fbfe49-b0ae-426b-ae03-f11fba4ce919",
  "importer": "folder",
  "isBundle": false,
  "bundleName": "",
  "priority": 1,
  "compressionType": {},
  "optimizeHotUpdate": {},
  "inlineSpriteFrames": {},
  "isRemoteBundle": {},
  "subMetas": {}
}

================================================
FILE: assets/Script/ECS.meta
================================================
{
  "ver": "1.1.3",
  "uuid": "bf25ebfe-4ae5-4c18-8033-bb2bc7293a03",
  "importer": "folder",
  "isBundle": false,
  "bundleName": "",
  "priority": 1,
  "compressionType": {},
  "optimizeHotUpdate": {},
  "inlineSpriteFrames": {},
  "isRemoteBundle": {},
  "subMetas": {}
}

================================================
FILE: assets/Script/Main.ts
================================================
import { ECSController } from "./Core/ECSController";
import { ECSWorld } from "./ECS/lib/ECSWorld";
import { SysAttack } from "./ECS/systems/SysAttack";
import { SysBehaviorTree } from "./ECS/systems/SysBehaviorTree";
import { ITouchProcessor, SysCocosView } from "./ECS/systems/SysCocosView";
import { SysMonitor } from "./ECS/systems/SysMonitor";
import { SysMovable } from "./ECS/systems/SysMovable";
import { SysRoleState } from "./ECS/systems/SysRoleState";
import { WorldCocosView } from "./ECS/worlds/WorldCocosView";

const {ccclass, property} = cc._decorator;

@ccclass
export default class Main extends cc.Component {
    private _world: ECSWorld = null;
    private _touchHandler: ITouchProcessor[] = [];

    private ecsController = new ECSController();

    protected onLoad(): void {
        cc.dynamicAtlasManager.enabled = true;
    }

    start () {
        this.ecsController.world = this._world = new WorldCocosView();
        this._world.createEntity();         // 创建0号实体
        this._world.addSystem(new SysBehaviorTree());   // 行为树
        this._world.addSystem(new SysMovable());        // 移动
        this._world.addSystem(new SysMonitor());        // 监视
        this._world.addSystem(new SysAttack());         // 攻击系统
        this._world.addSystem(new SysRoleState());      // role state
        this._world.addSystem(new SysCocosView());      // cocos view

        this.regiestTouchEvent();

        //this.regiestTouchHandler();

        

    }

    onClick1() {
        for(let i=0; i<1; i++) {
            this.ecsController.createRoleEntity("Biker");
        }
    }

    onClick2() {
        for(let i=0; i<1; i++) {
            this.ecsController.createRoleEntity("Cyborg");
        }
    }

    onClick3() {
        cc.debug.setDisplayStats(!cc.debug.isDisplayStats());
    }

    protected update(dt: number): void {
        if(this._world) this._world.update(dt);
    }

    private regiestTouchEvent() {
        this.node.on(cc.Node.EventType.TOUCH_START, this._onTouchStart, this);
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this._onTouchMove, this);
        this.node.on(cc.Node.EventType.TOUCH_END, this._onTouchEnd, this);
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this._onTouchCancel, this);
    }

    private _onTouchStart(e: cc.Event.EventTouch) {
        for(let i = 0; i < this._touchHandler.length; i++) {
            this._touchHandler[i].onTouchStart(e.getLocation(), this._world);   
        }
    }
    private _onTouchMove(e: cc.Event.EventTouch) {
        for(let i = 0; i < this._touchHandler.length; i++) {
            this._touchHandler[i].onTouchMove(e.getLocation(), this._world);   
        }
    }
    private _onTouchEnd(e: cc.Event.EventTouch) {
        for(let i = 0; i < this._touchHandler.length; i++) {
            this._touchHandler[i].onTouchEnd(e.getLocation(), this._world);   
        }
    }
    private _onTouchCancel(e: cc.Event.EventTouch) {
        for(let i = 0; i < this._touchHandler.length; i++) {
            this._touchHandler[i].onTouchCancel(e.getLocation(), this._world);   
        }
    }

    public regiestTouchHandler(handler: ITouchProcessor) {
        this._touchHandler.push(handler);
    }

    public unRegiestTouchHandler(handler:ITouchProcessor) {
        for(let i = this._touchHandler.length - 1; i >= 0; i--) {
            if(this._touchHandler[i] == handler) {
                this._touchHandler.splice(i, 1);
            }
        }
    }


    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<a.length; i++) {
                if(a[i] == 1) {
                    map[i] ++;
                }
            }
        }
        
    }

    
}


================================================
FILE: assets/Script/Main.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "e1b90feb-a217-4493-849d-9a611900d683",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/Struct/Direction.ts
================================================
export enum Direction {
    Up,
    Down,
    Left,
    Right
}

================================================
FILE: assets/Script/Struct/Direction.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "436daff0-c505-45e0-b0ea-d804b6ef7fac",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/Struct/NodeEvent.ts
================================================
export enum EventType {
    Stand,          
    Run,
    Attack,
    Hurt,
    HPChange,
    Death,
    GraphicsDraw,
}

export class EventBase {
    type: EventType;
    constructor(type:number) {
        this.type = type;
    }
}

export class EventStand extends EventBase {
    constructor() {
        super(EventType.Stand);
    }
}

export class EventRun extends EventBase {
    constructor() {
        super(EventType.Run);
    }
}

export class EventAttack extends EventBase {
    constructor() {
        super(EventType.Attack);
    }
}

export class EventHurt extends EventBase {
    constructor() {
        super(EventType.Hurt);
    }
}

export class EventDeath extends EventBase {
    callback: Function;
    constructor(cb: Function) {
        super(EventType.Death);
        this.callback = cb;
    }
}

export class EventHPChange extends EventBase {
    public lastHP: number;
    public nowHP: number;
    public maxHP: number;
    constructor(maxHP: number, lastHP: number, nowHP: number) {
        super(EventType.HPChange);
        this.maxHP = maxHP;
        this.lastHP = lastHP;
        this.nowHP = nowHP;
    }
}

export class EventGraphicsDraw extends EventBase {
    public points: cc.Vec2[];
    public color: cc.Color;
    constructor(points: cc.Vec2[], color?: cc.Color) {
        super(EventType.GraphicsDraw)
        this.points = points;
        this.color = color;
    }
}

================================================
FILE: assets/Script/Struct/NodeEvent.ts.meta
================================================
{
  "ver": "1.1.0",
  "uuid": "8bdaf2f1-e01a-449c-88ab-e35aa4741b9c",
  "importer": "typescript",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

================================================
FILE: assets/Script/Struct.meta
================================================
{
  "ver": "1.1.3",
  "uuid": "e2f8f29f-d6d0-4172-802f-80e64a869ccf",
  "importer": "folder",
  "isBundle": false,
  "bundleName": "",
  "priority": 1,
  "compressionType": {},
  "optimizeHotUpdate": {},
  "inlineSpriteFrames": {},
  "isRemoteBundle": {},
  "subMetas": {}
}

================================================
FILE: assets/Script.meta
================================================
{
  "ver": "1.1.3",
  "uuid": "4734c20c-0db8-4eb2-92ea-e692f4d70934",
  "importer": "folder",
  "isBundle": false,
  "bundleName": "",
  "priority": 1,
  "compressionType": {},
  "optimizeHotUpdate": {},
  "inlineSpriteFrames": {},
  "isRemoteBundle": {},
  "subMetas": {}
}

================================================
FILE: assets/Texture/HelloWorld.png.meta
================================================
{
  "ver": "2.3.7",
  "uuid": "6aa0aa6a-ebee-4155-a088-a687a6aadec4",
  "importer": "texture",
  "type": "sprite",
  "wrapMode": "clamp",
  "filterMode": "bilinear",
  "premultiplyAlpha": false,
  "genMipmaps": false,
  "packable": true,
  "width": 195,
  "height": 270,
  "platformSettings": {},
  "subMetas": {
    "HelloWorld": {
      "ver": "1.0.6",
      "uuid": "31bc895a-c003-4566-a9f3-2e54ae1c17dc",
      "importer": "sprite-frame",
      "rawTextureUuid": "6aa0aa6a-ebee-4155-a088-a687a6aadec4",
      "trimType": "none",
      "trimThreshold": 1,
      "rotated": false,
      "offsetX": 0,
      "offsetY": 0,
      "trimX": 0,
      "trimY": 0,
      "width": 195,
      "height": 270,
      "rawWidth": 195,
      "rawHeight": 270,
      "borderTop": 0,
      "borderBottom": 0,
      "borderLeft": 0,
      "borderRight": 0,
      "subMetas": {}
    }
  }
}

================================================
FILE: assets/Texture/singleColor.png.meta
================================================
{
  "ver": "2.3.7",
  "uuid": "a8027877-d8d6-4645-97a0-52d4a0123dba",
  "importer": "texture",
  "type": "sprite",
  "wrapMode": "clamp",
  "filterMode": "bilinear",
  "premultiplyAlpha": false,
  "genMipmaps": false,
  "packable": true,
  "width": 2,
  "height": 2,
  "platformSettings": {},
  "subMetas": {
    "singleColor": {
      "ver": "1.0.6",
      "uuid": "410fb916-8721-4663-bab8-34397391ace7",
      "importer": "sprite-frame",
      "rawTextureUuid": "a8027877-d8d6-4645-97a0-52d4a0123dba",
      "trimType": "none",
      "trimThreshold": 1,
      "rotated": false,
      "offsetX": 0,
      "offsetY": 0,
      "trimX": 0,
      "trimY": 0,
      "width": 2,
      "height": 2,
      "rawWidth": 2,
      "rawHeight": 2,
      "borderTop": 0,
      "borderBottom": 0,
      "borderLeft": 0,
      "borderRight": 0,
      "subMetas": {}
    }
  }
}

================================================
FILE: assets/Texture.meta
================================================
{
  "ver": "1.1.3",
  "uuid": "7b81d4e8-ec84-4716-968d-500ac1d78a54",
  "importer": "folder",
  "isBundle": false,
  "bundleName": "",
  "priority": 1,
  "compressionType": {},
  "optimizeHotUpdate": {},
  "inlineSpriteFrames": {},
  "isRemoteBundle": {},
  "subMetas": {}
}

================================================
FILE: assets/resources/3de2d4d5-8b98-4175-b44e-2516a9dae308113719czjoklju1eg0ued0.jpeg.meta
================================================
{
  "ver": "2.3.7",
  "uuid": "3e42396d-4216-47bc-85bb-2b53217ef9db",
  "importer": "texture",
  "type": "sprite",
  "wrapMode": "clamp",
  "filterMode": "bilinear",
  "premultiplyAlpha": false,
  "genMipmaps": false,
  "packable": true,
  "width": 1009,
  "height": 454,
  "platformSettings": {},
  "subMetas": {
    "3de2d4d5-8b98-4175-b44e-2516a9dae308113719czjoklju1eg0ued0": {
      "ver": "1.0.6",
      "uuid": "accc37bc-cb00-4a77-98df-a22077d6ab15",
      "importer": "sprite-frame",
      "rawTextureUuid": "3e42396d-4216-47bc-85bb-2b53217ef9db",
      "trimType": "auto",
      "trimThreshold": 1,
      "rotated": false,
      "offsetX": 0,
      "offsetY": 0,
      "trimX": 0,
      "trimY": 0,
      "width": 1009,
      "height": 454,
      "rawWidth": 1009,
      "rawHeight": 454,
      "borderTop": 0,
      "borderBottom": 0,
      "borderLeft": 0,
      "borderRight": 0,
      "subMetas": {}
    }
  }
}

================================================
FILE: assets/resources/Biker/Biker.prefab
================================================
[
  {
    "__type__": "cc.Prefab",
    "_name": "",
    "_objFlags": 0,
    "_native": "",
    "data": {
      "__id__": 1
    },
    "optimizationPolicy": 0,
    "asyncLoadAssets": false,
    "readonly": false
  },
  {
    "__type__": "cc.Node",
    "_name": "Biker",
    "_objFlags": 0,
    "_parent": null,
    "_children": [
      {
        "__id__": 2
      },
      {
        "__id__": 6
      }
    ],
    "_active": true,
    "_components": [
      {
        "__id__": 13
      },
      {
        "__id__": 14
      }
    ],
    "_prefab": {
      "__id__": 15
    },
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 0,
      "height": 0
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        -447.33,
        -180.474,
        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": ""
  },
  {
    "__type__": "cc.Node",
    "_name": "sp",
    "_objFlags": 0,
    "_parent": {
      "__id__": 1
    },
    "_children": [],
    "_active": true,
    "_components": [
      {
        "__id__": 3
      },
      {
        "__id__": 4
      }
    ],
    "_prefab": {
      "__id__": 5
    },
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 48,
      "height": 48
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.25,
      "y": 0
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        0,
        0,
        0,
        0,
        0,
        0,
        1,
        3,
        3,
        1
      ]
    },
    "_eulerAngles": {
      "__type__": "cc.Vec3",
      "x": 0,
      "y": 0,
      "z": 0
    },
    "_skewX": 0,
    "_skewY": 0,
    "_is3DNode": false,
    "_groupIndex": 0,
    "groupIndex": 0,
    "_id": ""
  },
  {
    "__type__": "cc.Sprite",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 2
    },
    "_enabled": true,
    "_materials": [
      {
        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
      }
    ],
    "_srcBlendFactor": 770,
    "_dstBlendFactor": 771,
    "_spriteFrame": {
      "__uuid__": "6a868846-77bb-4cd0-befb-52a3dfd16822"
    },
    "_type": 0,
    "_sizeMode": 1,
    "_fillType": 0,
    "_fillCenter": {
      "__type__": "cc.Vec2",
      "x": 0,
      "y": 0
    },
    "_fillStart": 0,
    "_fillRange": 0,
    "_isTrimmedMode": true,
    "_atlas": null,
    "_id": ""
  },
  {
    "__type__": "cc.Animation",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 2
    },
    "_enabled": true,
    "_defaultClip": {
      "__uuid__": "da671d3b-78c7-475c-9896-f0fe061c1840"
    },
    "_clips": [
      {
        "__uuid__": "6ee5314b-888f-409e-902e-26749cad0015"
      },
      {
        "__uuid__": "41ff0c6a-d2e8-4c9b-b789-bc4d370f7306"
      },
      {
        "__uuid__": "61a5270f-7761-498d-bbec-b994abd2c8a5"
      },
      {
        "__uuid__": "1cac62f0-3a28-49cd-928f-3411415323b9"
      },
      {
        "__uuid__": "62e0fbf7-19ce-44b3-a6b6-d24a24f0bdbd"
      },
      {
        "__uuid__": "da671d3b-78c7-475c-9896-f0fe061c1840"
      },
      {
        "__uuid__": "28fe88ff-4bc8-4075-8e33-036bc8590ed4"
      }
    ],
    "playOnLoad": true,
    "_id": ""
  },
  {
    "__type__": "cc.PrefabInfo",
    "root": {
      "__id__": 1
    },
    "asset": {
      "__id__": 0
    },
    "fileId": "32/npSD/5H0La6j9teJEMf",
    "sync": false
  },
  {
    "__type__": "cc.Node",
    "_name": "HP",
    "_objFlags": 0,
    "_parent": {
      "__id__": 1
    },
    "_children": [
      {
        "__id__": 7
      }
    ],
    "_active": true,
    "_components": [
      {
        "__id__": 10
      },
      {
        "__id__": 11
      }
    ],
    "_prefab": {
      "__id__": 12
    },
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 50,
      "height": 10
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        15,
        129.706,
        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": ""
  },
  {
    "__type__": "cc.Node",
    "_name": "value",
    "_objFlags": 512,
    "_parent": {
      "__id__": 6
    },
    "_children": [],
    "_active": true,
    "_components": [
      {
        "__id__": 8
      }
    ],
    "_prefab": {
      "__id__": 9
    },
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 0,
      "b": 0,
      "a": 255
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 50,
      "height": 10
    },
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0,
      "y": 0.5
    },
    "_trs": {
      "__type__": "TypedArray",
      "ctor": "Float64Array",
      "array": [
        -25,
        0,
        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": ""
  },
  {
    "__type__": "cc.Sprite",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 7
    },
    "_enabled": true,
    "_materials": [
      {
        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
      }
    ],
    "_srcBlendFactor": 770,
    "_dstBlendFactor": 771,
    "_spriteFrame": {
      "__uuid__": "67e68bc9-dad5-4ad9-a2d8-7e03d458e32f"
    },
    "_type": 1,
    "_sizeMode": 0,
    "_fillType": 0,
    "_fillCenter": {
      "__type__": "cc.Vec2",
      "x": 0,
      "y": 0
    },
    "_fillStart": 0,
    "_fillRange": 0,
    "_isTrimmedMode": true,
    "_atlas": null,
    "_id": ""
  },
  {
    "__type__": "cc.PrefabInfo",
    "root": {
      "__id__": 1
    },
    "asset": {
      "__id__": 0
    },
    "fileId": "89xzFFRJFFJJux2bcfP/16",
    "sync": false
  },
  {
    "__type__": "cc.Sprite",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 6
    },
    "_enabled": true,
    "_materials": [
      {
        "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
      }
    ],
    "_srcBlendFactor": 770,
    "_dstBlendFactor": 771,
    "_spriteFrame": {
      "__uuid__": "88e79fd5-96b4-4a77-a1f4-312467171014"
    },
    "_type": 1,
    "_sizeMode": 0,
    "_fillType": 0,
    "_fillCenter": {
      "__type__": "cc.Vec2",
      "x": 0,
      "y": 0
    },
    "_fillStart": 0,
    "_fillRange": 0,
    "_isTrimmedMode": true,
    "_atlas": null,
    "_id": ""
  },
  {
    "__type__": "cc.ProgressBar",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 6
    },
    "_enabled": true,
    "_N$totalLength": 50,
    "_N$barSprite": {
      "__id__": 8
    },
    "_N$mode": 0,
    "_N$progress": 1,
    "_N$reverse": false,
    "_id": ""
  },
  {
    "__type__": "cc.PrefabInfo",
    "root": {
      "__id__": 1
    },
    "asset": {
      "__id__": 0
    },
    "fileId": "6f4u0eKrBLg6uBBF8XiS5j",
    "sync": false
  },
  {
    "__type__": "d38f8EBpNRCKpXOZDdZv+gD",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 1
    },
    "_enabled": true,
    "anim": {
      "__id__": 4
    },
    "_id": ""
  },
  {
    "__type__": "cc.Graphics",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 1
    },
    "_enabled": true,
    "_materials": [
      {
        "__uuid__": "a153945d-2511-4c14-be7b-05d242f47d57"
      }
    ],
    "_lineWidth": 2,
    "_strokeColor": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 0,
      "b": 0,
      "a": 255
    },
    "_lineJoin": 2,
    "_lineCap": 0,
    "_fillColor": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_miterLimit": 10,
    "_id": ""
  },
  {
    "__type__": "cc.PrefabInfo",
    "root": {
      "__id__": 1
    },
    "asset": {
      "__id__": 0
    },
    "fileId": "",
    "sync": false
  }
]

================================================
FILE: assets/resources/Biker/Biker.prefab.meta
================================================
{
  "ver": "1.3.2",
  "uuid": "e3f2d00f-b307-4c62-93ae-b968945b1b9f",
  "importer": "prefab",
  "optimizationPolicy": "AUTO",
  "asyncLoadAssets": false,
  "readonly": false,
  "subMetas": {}
}

================================================
FILE: assets/resources/Biker/anims/attack.anim
================================================
{
  "__type__": "cc.AnimationClip",
  "_name": "attack",
  "_objFlags": 0,
  "_native": "",
  "_duration": 1.0166666666666666,
  "sample": 60,
  "speed": 1,
  "wrapMode": 1,
  "curveData": {
    "comps": {
      "cc.Sprite": {
        "spriteFrame": [
          {
            "frame": 0,
            "value": {
              "__uuid__": "36974693-ddd3-43de-994b-2f87d650afab"
            }
          },
          {
            "frame": 0.16666666666666666,
            "value": {
              "__uuid__": "e5b7949e-ab1a-485a-8652-81db128e6d2d"
            }
          },
          {
            "frame": 0.3333333333333333,
            "value": {
              "__uuid__": "70703165-d081-4711-9156-ec570fb12db9"
            }
          },
          {
            "frame": 0.5,
            "value": {
              "__uuid__": "4ccbf914-5142-4ba7-80f6-46a3503c4afe"
            }
          },
          {
            "frame": 0.6666666666666666,
            "value": {
              "__uuid__": "e7d042b9-f49a-4495-bb62-fcae6fa39cb3"
            }
          },
          {
            "frame": 0.8333333333333334,
            "value": {
              "__uuid__": "24dc980d-2426-41b9-91a7-9a664bd2f6b0"
            }
          },
          {
            "frame": 1,
            "value": {
              "__uuid__": "36974693-ddd3-43de-994b-2f87d650afab"
            }
          }
        ]
      }
    }
  },
  "events": []
}

================================================
FILE: assets/resources/Biker/anims/attack.anim.meta
================================================
{
  "ver": "2.1.2",
  "uuid": "6ee5314b-888f-409e-902e-26749cad0015",
  "importer": "animation-clip",
  "subMetas": {}
}

================================================
FILE: assets/resources/Biker/anims/death.anim
================================================
{
  "__type__": "cc.AnimationClip",
  "_name": "death",
  "_objFlags": 0,
  "_native": "",
  "_duration": 0.85,
  "sample": 60,
  "speed": 1,
  "wrapMode": 1,
  "curveData": {
    "comps": {
      "cc.Sprite": {
        "spriteFrame": [
          {
            "frame": 0,
            "value": {
              "__uuid__": "f5476f9b-3eac-4003-a7d9-868fbeb659fa"
            }
          },
          {
            "frame": 0.16666666666666666,
            "value": {
              "__uuid__": "0d4a7d9d-533a-4b37-a48d-bc4b4b5d3409"
            }
          },
          {
            "frame": 0.3333333333333333,
            "value": {
              "__uuid__": "1051eefe-7216-45c1-8f10-673f9dae689f"
            }
          },
          {
            "frame": 0.5,
            "value": {
              "__uuid__": "dde16e39-67b3-427e-8c49-53c00fb59dc7"
            }
          },
          {
            "frame": 0.6666666666666666,
            "value": {
              "__uuid__": "555da2d0-cb33-416b-95fc-4e21b3979e7b"
            }
          },
          {
            "frame": 0.8333333333333334,
            "value": {
              "__uuid__": "297a317b-d3f4-4495-a907-2d120eb45f93"
            }
          }
        ]
      }
    }
  },
  "events": []
}

================================================
FILE: assets/resources/Biker/anims/death.anim.meta
================================================
{
  "ver": "2.1.2",
  "uuid": "41ff0c6a-d2e8-4c9b-b789-bc4d370f7306",
  "importer": "animation-clip",
  "subMetas": {}
}

================================================
FILE: assets/resources/Biker/anims/hurt.anim
================================================
{
  "__type__": "cc.AnimationClip",
  "_name": "hurt",
  "_objFlags": 0,
  "_native": "",
  "_duration": 0.18333333333333332,
  "sample": 60,
  "speed": 1,
  "wrapMode": 1,
  "curveData": {
    "comps": {
      "cc.Sprite": {
        "spriteFrame": [
          {
            "frame": 0,
            "value": {
              "__uuid__": "4d3d9c32-a3e4-462c-9bd6-0e23c769bdb0"
            }
          },
          {
            "frame": 0.08333333333333333,
            "value": {
              "__uuid__": "877bb390-9e8f-4426-ae29-630095004e6d"
            }
          },
          {
            "frame": 0.16666666666666666,
            "value": {
              "__uuid__": "4d3d9c32-a3e4-462c-9bd6-0e23c769bdb0"
            }
          }
        ]
      }
    }
  },
  "events": []
}

================================================
FILE: assets/resources/Biker/anims/hurt.anim.meta
================================================
{
  "ver": "2.1.2",
  "uuid": "28fe88ff-4bc8-4075-8e33-036bc8590ed4",
  "importer": "animation-clip",
  "subMetas": {}
}

================================================
FILE: assets/resources/Biker/anims/punch.anim
================================================
{
  "__type__": "cc.AnimationClip",
  "_name": "punch",
  "_objFlags": 0,
  "_native": "",
  "_duration": 1.0166666666666666,
  "sample": 60,
  "speed": 1,
  "wrapMode": 1,
  "curveData": {
    "comps": {
      "cc.Sprite": {
        "spriteFrame": [
          {
            "frame": 0,
            "value": {
              "__uuid__": "f180d226-0504-4b60-ae35-40d47deac85a"
            }
          },
          {
            "frame": 0.16666666666666666,
            "value": {
              "__uuid__": "4328e236-573e-49e1-9922-523be4bbcffd"
            }
          },
          {
            "frame": 0.3333333333333333,
            "value": {
              "__uuid__": "443d0757-6fe2-4834-b162-26d77092ee5c"
            }
          },
          {
            "frame": 0.5,
            "value": {
              "__uuid__": "5b9ea29e-14bd-4376-be56-7641d93cdd45"
            }
          },
          {
            "frame": 0.6666666666666666,
            "value": {
              "__uuid__": "bf94064d-b1ae-42e6-8dce-c1bedea66e07"
            }
          },
          {
            "frame": 0.8333333333333334,
            "value": {
              "__uuid__": "7501f2da-6a8b-4a10-9908-ec67aff429f4"
            }
          },
          {
            "frame": 1,
            "value": {
              "__uuid__": "f180d226-0504-4b60-ae35-40d47deac85a"
            }
          }
        ]
      }
    }
  },
  "events": []
}

================================================
FILE: assets/resources/Biker/anims/punch.anim.meta
================================================
{
  "ver": "2.1.2",
  "uuid": "61a5270f-7761-498d-bbec-b994abd2c8a5",
  "importer": "animation-clip",
  "subMetas": {}
}

================================================
FILE: assets/resources/Biker/anims/run.anim
================================================
{
  "__type__": "cc.AnimationClip",
  "_name": "run",
  "_objFlags": 0,
  "_native": "",
  "_duration": 1.0166666666666666,
  "sample": 60,
  "speed": 1,
  "wrapMode": 2,
  "curveData": {
    "comps": {
      "cc.Sprite": {
        "spriteFrame": [
          {
            "frame": 0,
            "value": {
              "__uuid__": "541e4c96-93f5-4ccd-8d1b-b9e386d143c1"
            }
          },
          {
            "frame": 0.16666666666666666,
            "value": {
              "__uuid__": "e61ec58b-4144-437a-b053-090890f3fb81"
            }
          },
          {
            "frame": 0.3333333333333333,
            "value": {
              "__uuid__": "e7ae4439-ebc8-49eb-9ff6-8d255c822619"
            }
          },
          {
            "frame": 0.5,
            "value": {
              "__uuid__": "15102378-3270-4f81-a975-9fde0a542fdb"
            }
          },
          {
            "frame": 0.6666666666666666,
            "value": {
              "__uuid__": "a6252eac-25e4-4b98-8b85-05c4ba8e7641"
            }
          },
          {
            "frame": 0.8333333333333334,
            "value": {
              "__uuid__": "24a57346-5b93-4131-832b-ed6fdc48ec16"
            }
          },
          {
            "frame": 1,
            "value": {
              "__uuid__": "541e4c96-93f5-4ccd-8d1b-b9e386d143c1"
            }
          }
        ]
      }
    }
  },
  "events": []
}

================================================
FILE: assets/resources/Biker/anims/run.anim.meta
================================================
{
  "ver": "2.1.2",
  "uuid": "1cac62f0-3a28-49cd-928f-3411415323b9",
  "importer": "animation-clip",
  "subMetas": {}
}

================================================
FILE: assets/resources/Biker/anims/run_attack.anim
================================================
{
  "__type__": "cc.AnimationClip",
  "_name": "run_attack",
  "_objFlags": 0,
  "_native": "",
  "_duration": 1.0166666666666666,
  "sample": 60,
  "speed": 1,
  "wrapMode": 1,
  "curveData": {
    "comps": {
      "cc.Sprite": {
        "spriteFrame": [
          {
            "frame": 0,
            "value": {
              "__uuid__": "6589b771-3f5a-491e-8bc2-881a7462e3f7"
            }
          },
          {
            "frame": 0.16666666666666666,
            "value": {
              "__uuid__": "9a7da8fb-e686-4cec-baf9-4fbfd24cb6a0"
            }
          },
          {
            "frame": 0.3333333333333333,
            "value": {
              "__uuid__": "b06d453f-86ed-4630-bc36-73c0a97a2767"
            }
          },
          {
            "frame": 0.5,
            "value": {
              "__uuid__": "5a2a0b48-ed3b-4d7e-9896-6085d0a48464"
            }
          },
          {
            "frame": 0.6666666666666666,
            "value": {
              "__uuid__": "bc238bda-b094-4257-8a60-c8b54d69cb9a"
            }
          },
          {
            "frame": 0.8333333333333334,
            "value": {
              "__uuid__": "5e70746a-2039-42d2-b514-53c793c70ba7"
            }
          },
          {
            "frame": 1,
            "value": {
              "__uuid__": "6589b771-3f5a-491e-8bc2-881a7462e3f7"
            }
          }
        ]
      }
    }
  },
  "events": []
}

================================================
FILE: assets/resources/Biker/anims/run_attack.anim.meta
================================================
{
  "ver": "2.1.2",
  "uuid": "62e0fbf7-19ce-44b3-a6b6-d24a24f0bdbd",
  "importer": "animation-clip",
  "subMetas": {}
}

================================================
FILE: assets/resources/Biker/anims/stand.anim
================================================
{
  "__type__": "cc.AnimationClip",
  "_name": "stand",
  "_objFlags": 0,
  "_native": "",
  "_duration": 0.6833333333333333,
  "sample": 60,
  "speed": 1,
  "wrapMode": 2,
  "curveData": {
    "comps": {
      "cc.Sprite": {
        "spriteFrame": [
          {
            "frame": 0,
            "value": {
              "__uuid__": "6a868846-77bb-4cd0-befb-52a3dfd16822"
            }
          },
          {
            "frame": 0.16666666666666666,
            "value": {
              "__uuid__": "d371b2ea-7f2a-447c-a67c-9feb0d343119"
            }
          },
          {
            "frame": 0.3333333333333333,
            "value": {
              "__uuid__": "dd62555f-974e-4ac8-b033-cd9a87af2ee6"
            }
          },
          {
            "frame": 0.5,
            "value": {
              "__uuid__": "1f207051-8fbe-4977-9d29-548af893ee74"
            }
          },
          {
            "frame": 0.6666666666666666,
            "value": {
              "__uuid__": "6a868846-77bb-4cd0-befb-52a3dfd16822"
            }
          }
        ]
      }
    }
  },
  "events": []
}

================================================
FILE: assets/resources/Biker/anims/stand.anim.meta
================================================
{
  "ver": "2.1.2",
  "uuid": "da671d3b-78c7-475c-9896-f0fe061c1840",
  "importer": "animation-clip",
  "subMetas": {}
}

================================================
FILE: assets/resources/Biker/anims.meta
================================================
{
  "ver": "1.1.3",
  "uuid": "6dabbe66-aa6b-4573-9fa1-3da50292f5a1",
  "importer": "folder",
  "isBundle": false,
  "bundleName": "",
  "priority": 1,
  "compressionType": {},
  "optimizeHotUpdate": {},
  "inlineSpriteFrames": {},
  "isRemoteBundle": {},
  "subMetas": {}
}

================================================
FILE: assets/resources/Biker/textures/Biker_attack1_01.png.meta
================================================
{
  "ver": "2.3.7",
  "uuid": "397ddf1a-3b92-45a3-9987-1489244a0b70",
  "importer": "texture",
  "type": "sprite",
  "wrapMode": "clamp",
  "filterMode": "point",
  "premultiplyAlpha": false,
  "genMipmaps": false,
  "packable": true,
  "width": 48,
  "height": 48,
  "platformSettings": {},
  "subMetas": {
    "Biker_attack1_01": {
      "ver": "1.0.6",
      "uuid": "36974693-ddd3-43de-994b-2f87d650afab",
      "importer": "sprite-frame",
      "rawTextureUuid": "397ddf1a-3b92-45a3-9987-1489244a0b70",
      "trimType": "none",
      "trimThreshold": 1,
      "rotated": false,
      "offsetX": 0,
      "offsetY": 0,
      "trimX": 0,
      "trimY": 0,
      "width": 48,
      "height": 48,
      "rawWidth": 48,
      "rawHeight": 48,
      "borderTop": 0,
      "borderBottom": 0,
      "borderLeft": 0,
      "borderRight": 0,
      "subMetas": {}
    }
  }
}

================================================
FILE: assets/resources/Biker/textures/Biker_attack1_02.png.meta
================================================
{
  "ver": "2.3.7",
  "uuid": "8c655051-ccbe-4b02-9618-ccfff782d182",
  "importer": "texture",
  "type": "sprite",
  "wrapMod
Download .txt
gitextract_se9l75kc/

├── .gitignore
├── BehaviorTree.dio
├── ECS.dio
├── LICENSE
├── README.md
├── assets/
│   ├── Scene/
│   │   ├── helloworld.fire
│   │   └── helloworld.fire.meta
│   ├── Scene.meta
│   ├── Script/
│   │   ├── Common/
│   │   │   ├── BehaviorTree.ts
│   │   │   ├── BehaviorTree.ts.meta
│   │   │   ├── CocosHelper.ts
│   │   │   ├── CocosHelper.ts.meta
│   │   │   ├── FrameAnimation.ts
│   │   │   └── FrameAnimation.ts.meta
│   │   ├── Common.meta
│   │   ├── Core/
│   │   │   ├── ECSController.ts
│   │   │   ├── ECSController.ts.meta
│   │   │   ├── EventProcess.ts
│   │   │   ├── EventProcess.ts.meta
│   │   │   ├── RoleEventProcess.ts
│   │   │   └── RoleEventProcess.ts.meta
│   │   ├── Core.meta
│   │   ├── ECS/
│   │   │   ├── components/
│   │   │   │   ├── ComAttackable.ts
│   │   │   │   ├── ComAttackable.ts.meta
│   │   │   │   ├── ComBeAttacked.ts
│   │   │   │   ├── ComBeAttacked.ts.meta
│   │   │   │   ├── ComBehaviorTree.ts
│   │   │   │   ├── ComBehaviorTree.ts.meta
│   │   │   │   ├── ComCocosNode.ts
│   │   │   │   ├── ComCocosNode.ts.meta
│   │   │   │   ├── ComMonitor.ts
│   │   │   │   ├── ComMonitor.ts.meta
│   │   │   │   ├── ComMovable.ts
│   │   │   │   ├── ComMovable.ts.meta
│   │   │   │   ├── ComNodeConfig.ts
│   │   │   │   ├── ComNodeConfig.ts.meta
│   │   │   │   ├── ComRoleConfig.ts
│   │   │   │   ├── ComRoleConfig.ts.meta
│   │   │   │   ├── ComTransform.ts
│   │   │   │   └── ComTransform.ts.meta
│   │   │   ├── components.meta
│   │   │   ├── lib/
│   │   │   │   ├── Const.ts
│   │   │   │   ├── Const.ts.meta
│   │   │   │   ├── ECSComponent.ts
│   │   │   │   ├── ECSComponent.ts.meta
│   │   │   │   ├── ECSComponentPool.ts
│   │   │   │   ├── ECSComponentPool.ts.meta
│   │   │   │   ├── ECSFilter.ts
│   │   │   │   ├── ECSFilter.ts.meta
│   │   │   │   ├── ECSSystem.ts
│   │   │   │   ├── ECSSystem.ts.meta
│   │   │   │   ├── ECSWorld.ts
│   │   │   │   └── ECSWorld.ts.meta
│   │   │   ├── lib.meta
│   │   │   ├── systems/
│   │   │   │   ├── SysAttack.ts
│   │   │   │   ├── SysAttack.ts.meta
│   │   │   │   ├── SysBehaviorTree.ts
│   │   │   │   ├── SysBehaviorTree.ts.meta
│   │   │   │   ├── SysCocosView.ts
│   │   │   │   ├── SysCocosView.ts.meta
│   │   │   │   ├── SysMonitor.ts
│   │   │   │   ├── SysMonitor.ts.meta
│   │   │   │   ├── SysMovable.ts
│   │   │   │   ├── SysMovable.ts.meta
│   │   │   │   ├── SysRoleState.ts
│   │   │   │   └── SysRoleState.ts.meta
│   │   │   ├── systems.meta
│   │   │   ├── worlds/
│   │   │   │   ├── WorldCocosView.ts
│   │   │   │   └── WorldCocosView.ts.meta
│   │   │   └── worlds.meta
│   │   ├── ECS.meta
│   │   ├── Main.ts
│   │   ├── Main.ts.meta
│   │   ├── Struct/
│   │   │   ├── Direction.ts
│   │   │   ├── Direction.ts.meta
│   │   │   ├── NodeEvent.ts
│   │   │   └── NodeEvent.ts.meta
│   │   └── Struct.meta
│   ├── Script.meta
│   ├── Texture/
│   │   ├── HelloWorld.png.meta
│   │   └── singleColor.png.meta
│   ├── Texture.meta
│   ├── resources/
│   │   ├── 3de2d4d5-8b98-4175-b44e-2516a9dae308113719czjoklju1eg0ued0.jpeg.meta
│   │   ├── Biker/
│   │   │   ├── Biker.prefab
│   │   │   ├── Biker.prefab.meta
│   │   │   ├── anims/
│   │   │   │   ├── attack.anim
│   │   │   │   ├── attack.anim.meta
│   │   │   │   ├── death.anim
│   │   │   │   ├── death.anim.meta
│   │   │   │   ├── hurt.anim
│   │   │   │   ├── hurt.anim.meta
│   │   │   │   ├── punch.anim
│   │   │   │   ├── punch.anim.meta
│   │   │   │   ├── run.anim
│   │   │   │   ├── run.anim.meta
│   │   │   │   ├── run_attack.anim
│   │   │   │   ├── run_attack.anim.meta
│   │   │   │   ├── stand.anim
│   │   │   │   └── stand.anim.meta
│   │   │   ├── anims.meta
│   │   │   ├── textures/
│   │   │   │   ├── Biker_attack1_01.png.meta
│   │   │   │   ├── Biker_attack1_02.png.meta
│   │   │   │   ├── Biker_attack1_03.png.meta
│   │   │   │   ├── Biker_attack1_04.png.meta
│   │   │   │   ├── Biker_attack1_05.png.meta
│   │   │   │   ├── Biker_attack1_06.png.meta
│   │   │   │   ├── Biker_death_01.png.meta
│   │   │   │   ├── Biker_death_02.png.meta
│   │   │   │   ├── Biker_death_03.png.meta
│   │   │   │   ├── Biker_death_04.png.meta
│   │   │   │   ├── Biker_death_05.png.meta
│   │   │   │   ├── Biker_death_06.png.meta
│   │   │   │   ├── Biker_doublejump_01.png.meta
│   │   │   │   ├── Biker_doublejump_02.png.meta
│   │   │   │   ├── Biker_doublejump_03.png.meta
│   │   │   │   ├── Biker_doublejump_04.png.meta
│   │   │   │   ├── Biker_doublejump_05.png.meta
│   │   │   │   ├── Biker_doublejump_06.png.meta
│   │   │   │   ├── Biker_hurt_01.png.meta
│   │   │   │   ├── Biker_hurt_02.png.meta
│   │   │   │   ├── Biker_idle_01.png.meta
│   │   │   │   ├── Biker_idle_02.png.meta
│   │   │   │   ├── Biker_idle_03.png.meta
│   │   │   │   ├── Biker_idle_04.png.meta
│   │   │   │   ├── Biker_jump_01.png.meta
│   │   │   │   ├── Biker_jump_02.png.meta
│   │   │   │   ├── Biker_jump_03.png.meta
│   │   │   │   ├── Biker_jump_04.png.meta
│   │   │   │   ├── Biker_punch_01.png.meta
│   │   │   │   ├── Biker_punch_02.png.meta
│   │   │   │   ├── Biker_punch_03.png.meta
│   │   │   │   ├── Biker_punch_04.png.meta
│   │   │   │   ├── Biker_punch_05.png.meta
│   │   │   │   ├── Biker_punch_06.png.meta
│   │   │   │   ├── Biker_run_01.png.meta
│   │   │   │   ├── Biker_run_02.png.meta
│   │   │   │   ├── Biker_run_03.png.meta
│   │   │   │   ├── Biker_run_04.png.meta
│   │   │   │   ├── Biker_run_05.png.meta
│   │   │   │   ├── Biker_run_06.png.meta
│   │   │   │   ├── Biker_run_attack_01.png.meta
│   │   │   │   ├── Biker_run_attack_02.png.meta
│   │   │   │   ├── Biker_run_attack_03.png.meta
│   │   │   │   ├── Biker_run_attack_04.png.meta
│   │   │   │   ├── Biker_run_attack_05.png.meta
│   │   │   │   └── Biker_run_attack_06.png.meta
│   │   │   └── textures.meta
│   │   ├── Biker.meta
│   │   ├── Cyborg/
│   │   │   ├── Cyborg.prefab
│   │   │   ├── Cyborg.prefab.meta
│   │   │   ├── anims/
│   │   │   │   ├── attack.anim
│   │   │   │   ├── attack.anim.meta
│   │   │   │   ├── death.anim
│   │   │   │   ├── death.anim.meta
│   │   │   │   ├── hurt.anim
│   │   │   │   ├── hurt.anim.meta
│   │   │   │   ├── punch.anim
│   │   │   │   ├── punch.anim.meta
│   │   │   │   ├── run.anim
│   │   │   │   ├── run.anim.meta
│   │   │   │   ├── run_attack.anim
│   │   │   │   ├── run_attack.anim.meta
│   │   │   │   ├── stand.anim
│   │   │   │   └── stand.anim.meta
│   │   │   ├── anims.meta
│   │   │   ├── textures/
│   │   │   │   ├── Cyborg_attack1_01.png.meta
│   │   │   │   ├── Cyborg_attack1_02.png.meta
│   │   │   │   ├── Cyborg_attack1_03.png.meta
│   │   │   │   ├── Cyborg_attack1_04.png.meta
│   │   │   │   ├── Cyborg_attack1_05.png.meta
│   │   │   │   ├── Cyborg_attack1_06.png.meta
│   │   │   │   ├── Cyborg_death_01.png.meta
│   │   │   │   ├── Cyborg_death_02.png.meta
│   │   │   │   ├── Cyborg_death_03.png.meta
│   │   │   │   ├── Cyborg_death_04.png.meta
│   │   │   │   ├── Cyborg_death_05.png.meta
│   │   │   │   ├── Cyborg_death_06.png.meta
│   │   │   │   ├── Cyborg_doublejump_01.png.meta
│   │   │   │   ├── Cyborg_doublejump_02.png.meta
│   │   │   │   ├── Cyborg_doublejump_03.png.meta
│   │   │   │   ├── Cyborg_doublejump_04.png.meta
│   │   │   │   ├── Cyborg_doublejump_05.png.meta
│   │   │   │   ├── Cyborg_doublejump_06.png.meta
│   │   │   │   ├── Cyborg_hurt_01.png.meta
│   │   │   │   ├── Cyborg_hurt_02.png.meta
│   │   │   │   ├── Cyborg_idle_01.png.meta
│   │   │   │   ├── Cyborg_idle_02.png.meta
│   │   │   │   ├── Cyborg_idle_03.png.meta
│   │   │   │   ├── Cyborg_idle_04.png.meta
│   │   │   │   ├── Cyborg_jump_01.png.meta
│   │   │   │   ├── Cyborg_jump_02.png.meta
│   │   │   │   ├── Cyborg_jump_03.png.meta
│   │   │   │   ├── Cyborg_jump_04.png.meta
│   │   │   │   ├── Cyborg_punch_01.png.meta
│   │   │   │   ├── Cyborg_punch_02.png.meta
│   │   │   │   ├── Cyborg_punch_03.png.meta
│   │   │   │   ├── Cyborg_punch_04.png.meta
│   │   │   │   ├── Cyborg_punch_05.png.meta
│   │   │   │   ├── Cyborg_punch_06.png.meta
│   │   │   │   ├── Cyborg_run_01.png.meta
│   │   │   │   ├── Cyborg_run_02.png.meta
│   │   │   │   ├── Cyborg_run_03.png.meta
│   │   │   │   ├── Cyborg_run_04.png.meta
│   │   │   │   ├── Cyborg_run_05.png.meta
│   │   │   │   ├── Cyborg_run_06.png.meta
│   │   │   │   ├── Cyborg_run_attack_01.png.meta
│   │   │   │   ├── Cyborg_run_attack_02.png.meta
│   │   │   │   ├── Cyborg_run_attack_03.png.meta
│   │   │   │   ├── Cyborg_run_attack_04.png.meta
│   │   │   │   ├── Cyborg_run_attack_05.png.meta
│   │   │   │   └── Cyborg_run_attack_06.png.meta
│   │   │   └── textures.meta
│   │   ├── Cyborg.meta
│   │   ├── item.prefab
│   │   └── item.prefab.meta
│   └── resources.meta
├── creator.d.ts
├── jsconfig.json
├── project.json
├── role1behaviortree.dio
├── settings/
│   ├── builder.json
│   ├── builder.panel.json
│   ├── project.json
│   └── services.json
├── template.json
├── tsconfig.json
└── 行为树决策的时效性.md
Download .txt
SYMBOL INDEX (796 symbols across 31 files)

FILE: assets/Script/Common/BehaviorTree.ts
  class BlackBoard (line 13) | class BlackBoard {
  class ExecuteContext (line 17) | class ExecuteContext {
    method init (line 24) | public init(executor: SysBehaviorTree, world: ECSWorld) {
    method set (line 29) | public set(entity: number, dt: number, bb: BlackBoard) {
  type NodeState (line 37) | enum NodeState {
  type NodeType (line 45) | enum NodeType {
  class NodeBase (line 77) | class NodeBase {
    method constructor (line 81) | constructor(type: NodeType) {
  class CombineNode (line 87) | class CombineNode extends NodeBase {
    method constructor (line 90) | public constructor(type: NodeType, children: NodeBase[]) {
  class SequenceNode (line 96) | class SequenceNode extends CombineNode {
    method constructor (line 100) | constructor(children: NodeBase[], ignoreFailture = false) {
  class LockedSequenceNode (line 107) | class LockedSequenceNode extends CombineNode {
    method constructor (line 111) | constructor(children: NodeBase[], ignoreFailture = false) {
  class SelectorNode (line 118) | class SelectorNode extends CombineNode {
    method constructor (line 121) | constructor(children: NodeBase[], ) {
  class RandomSelectorNode (line 127) | class RandomSelectorNode extends CombineNode {
    method constructor (line 130) | constructor(children: NodeBase[], weigets?: number[]) {
  class ParallelNode (line 137) | class ParallelNode extends CombineNode {
    method constructor (line 139) | constructor(children: NodeBase[], ignoreFailture: boolean) {
  class DecoratorNode (line 146) | class DecoratorNode extends NodeBase {
    method constructor (line 148) | public constructor(type: NodeType, child: NodeBase) {
  class InverterNode (line 155) | class InverterNode extends DecoratorNode {
    method constructor (line 156) | constructor(child: NodeBase) {
  class SuccessNode (line 162) | class SuccessNode extends DecoratorNode {
    method constructor (line 163) | constructor(child: NodeBase) {
  class FailNode (line 169) | class FailNode extends DecoratorNode {
    method constructor (line 170) | constructor(child: NodeBase) {
  class RepeaterNode (line 176) | class RepeaterNode extends DecoratorNode {
    method constructor (line 180) | constructor(child: NodeBase, repeatCount: number, mustSuccess = false) {
  class RetryTillSuccess (line 188) | class RetryTillSuccess extends DecoratorNode {
    method constructor (line 191) | constructor(child: NodeBase, timeout:number) {
  class WaitNode (line 199) | class WaitNode extends NodeBase {
    method constructor (line 203) | constructor(seconds:number) {
  class WalkToPosNode (line 210) | class WalkToPosNode extends NodeBase {
    method constructor (line 213) | constructor(speed: number, pos: cc.Vec2) {
  class WalkToRandomPosNode (line 220) | class WalkToRandomPosNode extends NodeBase {
    method constructor (line 223) | constructor(speed: number, size: cc.Size) {
  class WalkToTargetNode (line 230) | class WalkToTargetNode extends NodeBase {
    method constructor (line 232) | constructor(speed: number) {
  class MonitorNode (line 238) | class MonitorNode extends NodeBase {
    method constructor (line 239) | constructor() {
  class AttackNode (line 244) | class AttackNode extends NodeBase {
    method constructor (line 245) | constructor() {
  class EnoughAttrNode (line 250) | class EnoughAttrNode extends NodeBase {
    method constructor (line 254) | constructor(com: {prototype: any}, attr: string, value: number) {
  class WillBeAttackedNode (line 262) | class WillBeAttackedNode extends NodeBase {
    method constructor (line 263) | constructor() {
  class AvoidNode (line 268) | class AvoidNode extends NodeBase {
    method constructor (line 270) | constructor(speed: number) {
  class RunAwayNode (line 276) | class RunAwayNode extends NodeBase {
    method constructor (line 277) | constructor() {
  class InAttackingNode (line 282) | class InAttackingNode extends NodeBase {
    method constructor (line 283) | constructor() {
  class NodeHandler (line 288) | class NodeHandler {
  method onEnter (line 297) | onEnter(node: SequenceNode, context: ExecuteContext) : void {
  method onUpdate (line 302) | onUpdate(node: SequenceNode, context: ExecuteContext) : void {
  method onEnter (line 334) | onEnter(node: LockedSequenceNode, context: ExecuteContext) : void {
  method onUpdate (line 339) | onUpdate(node: LockedSequenceNode, context: ExecuteContext) : void {
  method onEnter (line 365) | onEnter(node: SelectorNode, context: ExecuteContext) : void {
  method onUpdate (line 370) | onUpdate(node: SelectorNode, context: ExecuteContext) : void {
  method onEnter (line 397) | onEnter(node: RandomSelectorNode, context: ExecuteContext) : void {
  method onUpdate (line 414) | onUpdate(node: RandomSelectorNode, context: ExecuteContext) : void {
  method onEnter (line 424) | onEnter(node: ParallelNode, context: ExecuteContext) : void {
  method onUpdate (line 430) | onUpdate(node: ParallelNode, context: ExecuteContext) : void {
  method onEnter (line 453) | onEnter(node: InverterNode, context: ExecuteContext) : void {
  method onUpdate (line 457) | onUpdate(node: InverterNode, context: ExecuteContext) : void {
  method onEnter (line 467) | onEnter(node: SuccessNode, context: ExecuteContext) : void {
  method onUpdate (line 471) | onUpdate(node: SuccessNode, context: ExecuteContext) : void {
  method onEnter (line 481) | onEnter(node: FailNode, context: ExecuteContext) : void {
  method onUpdate (line 485) | onUpdate(node: FailNode, context: ExecuteContext) : void {
  method onEnter (line 495) | onEnter(node: RepeaterNode, context: ExecuteContext) : void {
  method onUpdate (line 500) | onUpdate(node: RepeaterNode, context: ExecuteContext) : void {
  method onEnter (line 516) | onEnter(node: RetryTillSuccess, context: ExecuteContext) : void {
  method onUpdate (line 522) | onUpdate(node: RetryTillSuccess, context: ExecuteContext) : void {
  method onEnter (line 545) | onEnter(node: WaitNode, context: ExecuteContext) : void {
  method onUpdate (line 549) | onUpdate(node: WaitNode, context: ExecuteContext) : void {
  method onEnter (line 560) | onEnter(node: WalkToPosNode, context: ExecuteContext) : void {
  method onUpdate (line 572) | onUpdate(node: WalkToPosNode, context: ExecuteContext) : void {
  method onEnter (line 583) | onEnter(node: WalkToRandomPosNode, context: ExecuteContext) : void {
  method onUpdate (line 597) | onUpdate(node: WalkToPosNode, context: ExecuteContext) : void {
  method onEnter (line 608) | onEnter(node: WalkToTargetNode, context: ExecuteContext) : void {
  method onUpdate (line 625) | onUpdate(node: WalkToTargetNode, context: ExecuteContext) : void {
  method onEnter (line 654) | onEnter(node: MonitorNode, context: ExecuteContext) : void {
  method onUpdate (line 659) | onUpdate(node: MonitorNode, context: ExecuteContext) : void {
  method onEnter (line 667) | onEnter(node: AttackNode, context: ExecuteContext) : void {
  method onUpdate (line 688) | onUpdate(node: AttackNode, context: ExecuteContext) : void {
  method onEnter (line 700) | onEnter(node: EnoughAttrNode, context: ExecuteContext) : void {
  method onUpdate (line 705) | onUpdate(node: EnoughAttrNode, context: ExecuteContext) : void {
  method onEnter (line 714) | onEnter(node: WillBeAttackedNode, context: ExecuteContext) : void {
  method onUpdate (line 720) | onUpdate(node: WillBeAttackedNode, context: ExecuteContext) : void {
  method onEnter (line 732) | onEnter(node: AvoidNode, context: ExecuteContext) : void {
  method onUpdate (line 748) | onUpdate(node: AvoidNode, context: ExecuteContext) : void {
  method onEnter (line 764) | onEnter(node: InAttackingNode, context: ExecuteContext) : void {
  method onUpdate (line 769) | onUpdate(node: InAttackingNode, context: ExecuteContext) : void {

FILE: assets/Script/Common/CocosHelper.ts
  class LoadProgress (line 1) | class LoadProgress {
  class CocosHelper (line 10) | class CocosHelper {
    method callInNextTick (line 12) | public static async callInNextTick() {
    method runRepeatTweenSync (line 38) | public static async runRepeatTweenSync(target: any, repeat: number, .....
    method runTweenSync (line 54) | public static async runTweenSync(target: any, ...tweens: cc.Tween[]): ...
    method stopTween (line 66) | public stopTween(target: any) {
    method stopTweenByTag (line 69) | public stopTweenByTag(tag: number) {
    method runActionSync (line 73) | public static async runActionSync(node: cc.Node, ...actions: cc.Finite...
    method runAnimSync (line 84) | public static async runAnimSync(node: cc.Node, animName?: string | num...
    method loadResThrowErrorSync (line 107) | public static loadResThrowErrorSync<T>(url: string, type: typeof cc.As...
    method loadRes (line 112) | public static loadRes<T>(url: string, type: typeof cc.Asset, callback:...
    method loadResSync (line 128) | public static loadResSync<T>(url: string, type: typeof cc.Asset, onPro...
    method _onProgress (line 145) | private static _onProgress(completedCount: number, totalCount: number,...
    method findChildInNode (line 154) | public static findChildInNode(nodeName: string, rootNode: cc.Node): cc...
    method getComponentName (line 168) | public static getComponentName(com: Function) {
    method loadBundleSync (line 176) | public static loadBundleSync(url: string, options: any): Promise<cc.As...
    method loadAssetFromBundleSync (line 190) | public static loadAssetFromBundleSync(bundleName: string, url: string) {
    method loadAssetSync (line 209) | public static loadAssetSync(url: string) {
    method releaseAsset (line 223) | public static releaseAsset(assets: cc.Asset | cc.Asset[]) {
    method addRef (line 227) | private static addRef(assets: cc.Asset | cc.Asset[]) {
    method decRes (line 237) | private static decRes(assets: cc.Asset | cc.Asset[]) {
    method captureScreen (line 248) | public static captureScreen(camera: cc.Camera, prop?: cc.Node | cc.Rec...
    method tweenFloat (line 270) | public static tweenFloat(from: number, to: number, duration: number, o...
    method tweenVec2 (line 283) | public static tweenVec2(from: cc.Vec2, to: cc.Vec2, duration: number, ...

FILE: assets/Script/Common/FrameAnimation.ts
  class FrameConfig (line 3) | @ccclass('FrameConfig')
  class FrameAnimation (line 12) | class FrameAnimation extends cc.Component {
    method start (line 29) | start () {
    method play (line 47) | play(configIdx: number, loop: boolean, callback?: Function) {
    method stop (line 55) | stop() {
    method update (line 59) | update (dt: number) {

FILE: assets/Script/Core/ECSController.ts
  class ECSController (line 13) | class ECSController<T extends ECSWorld> {
    method createRoleEntity (line 15) | public createRoleEntity(name: string) {

FILE: assets/Script/Core/EventProcess.ts
  class EventProcess (line 6) | class EventProcess extends cc.Component {
    method onAttach (line 7) | public onAttach(): void {
    method onDetach (line 11) | public onDetach(): void {
    method processEvent (line 15) | public processEvent(event: EventBase): void {
    method sync (line 19) | public sync(x: number, y: number, dir: cc.Vec2) {

FILE: assets/Script/Core/RoleEventProcess.ts
  class RoleEventProcess (line 8) | class RoleEventProcess extends EventProcess {
    method start (line 13) | start () {
    method onAttach (line 17) | onAttach(): void {
    method onDetach (line 21) | onDetach(): void {
    method processEvent (line 25) | processEvent(event: EventBase): void {
    method _changeHP (line 75) | private _changeHP(event: EventHPChange) {
    method _graphicsDraw (line 84) | private _graphicsDraw(event: EventGraphicsDraw) {
    method sync (line 105) | public sync(x: number, y: number, dir: cc.Vec2) {

FILE: assets/Script/ECS/components/ComAttackable.ts
  class ComAttackable (line 5) | class ComAttackable {

FILE: assets/Script/ECS/components/ComBeAttacked.ts
  class ComBeAttacked (line 5) | class ComBeAttacked {

FILE: assets/Script/ECS/components/ComBehaviorTree.ts
  class ComBehaviorTree (line 6) | class ComBehaviorTree {

FILE: assets/Script/ECS/components/ComCocosNode.ts
  class ComCocosNode (line 6) | class ComCocosNode {

FILE: assets/Script/ECS/components/ComMonitor.ts
  class ComMonitor (line 5) | class ComMonitor {

FILE: assets/Script/ECS/components/ComMovable.ts
  class ComMovable (line 5) | class ComMovable {

FILE: assets/Script/ECS/components/ComNodeConfig.ts
  class ComNodeConfig (line 5) | class ComNodeConfig {

FILE: assets/Script/ECS/components/ComRoleConfig.ts
  class ComRoleConfig (line 6) | class ComRoleConfig {

FILE: assets/Script/ECS/components/ComTransform.ts
  class ComTransform (line 5) | class ComTransform {

FILE: assets/Script/ECS/lib/Const.ts
  type EntityIndex (line 2) | type EntityIndex = number;
  type ComPoolIndex (line 4) | type ComPoolIndex = number;
  type ComType (line 6) | enum ComType {

FILE: assets/Script/ECS/lib/ECSComponent.ts
  type ECSComConstructor (line 4) | interface ECSComConstructor extends Function {
  type ECSTypedComConstructor (line 8) | interface ECSTypedComConstructor<T> extends ECSComConstructor {
  function RegistComConstructor (line 14) | function RegistComConstructor(comType: ComType, func: ECSComConstructor) {
  function GetComConstructor (line 17) | function GetComConstructor(comType: ComType) {
  function SetComConstructorType (line 22) | function SetComConstructorType(comCons: ECSComConstructor, type: ComType) {
  function GetComConstructorType (line 25) | function GetComConstructorType<T>(comCons: {prototype: T}): ComType {
  function ECSComponent (line 30) | function ECSComponent(type: ComType) {

FILE: assets/Script/ECS/lib/ECSComponentPool.ts
  class ECSComponentPool (line 7) | class ECSComponentPool<T> {
    method constructor (line 9) | public constructor(comCons: ECSTypedComConstructor<T>) {
    method get (line 17) | public get(idx: ComPoolIndex): T {
    method alloc (line 21) | public alloc(): ComPoolIndex {
    method free (line 32) | public free(idx: ComPoolIndex) {

FILE: assets/Script/ECS/lib/ECSFilter.ts
  class ECSFilter (line 4) | class ECSFilter {
    method constructor (line 12) | public constructor(world: ECSWorld, accepts?: ComType[], rejects?: Com...
    method entities (line 18) | public get entities() {
    method onEntityEnter (line 22) | public onEntityEnter(entity: EntityIndex) {
    method onEntityLeave (line 31) | public onEntityLeave(entity: EntityIndex) {
    method walk (line 39) | public walk(callback?: (entity: number) => boolean) {
    method isAccept (line 45) | public isAccept(entityIndex: EntityIndex) {
    method isContains (line 59) | public isContains(entity: number) {

FILE: assets/Script/ECS/lib/ECSWorld.ts
  class ECSWorld (line 8) | class ECSWorld {
    method getComponentPool (line 17) | public getComponentPool<T>(typeOrFunc: ComType | {prototype: T}): ECSC...
    method addSystem (line 26) | public addSystem(system: ECSSystem) {
    method removeSystem (line 35) | public removeSystem(system: ECSSystem) {
    method createEntity (line 48) | public createEntity(): number {
    method removeEntity (line 64) | public removeEntity(entityIndex: EntityIndex): boolean {
    method getComponentPoolIdx (line 82) | public getComponentPoolIdx<T>(entityIndex: EntityIndex, com: {prototyp...
    method getComponent (line 89) | public getComponent<T>(entityIndex: EntityIndex, com: {prototype: T} |...
    method addComponent (line 95) | public addComponent<T>(entityIndex: EntityIndex, com: {prototype: T}, ...
    method removeComponent (line 108) | public removeComponent(entityIndex: EntityIndex, com: ECSComConstructo...
    method removeAllComponents (line 120) | public removeAllComponents(entityIndex: EntityIndex, dirty = true) {
    method getSingletonComponent (line 131) | public getSingletonComponent<T>(com: {prototype: T}): T {
    method setEntityDirty (line 139) | public setEntityDirty(entityIndex: EntityIndex): void {
    method getFilter (line 149) | public getFilter(fillterKey: string): ECSFilter {
    method update (line 167) | public update(dt:number) {
    method _realRemoveEntity (line 176) | private _realRemoveEntity() {
  function GenFillterKey (line 185) | function GenFillterKey(accepts: ECSComConstructor[], rejects?: ECSComCon...

FILE: assets/Script/ECS/systems/SysAttack.ts
  constant FILTER_ATTACKABLE (line 9) | const FILTER_ATTACKABLE = GenFillterKey([ComTransform, ComAttackable, Co...
  constant FILTER_BEATTACKED (line 10) | const FILTER_BEATTACKED = GenFillterKey([ComBeAttacked]);
  class SysAttack (line 11) | class SysAttack extends ECSSystem {
    method onAdd (line 13) | public onAdd(world: ECSWorld): void {
    method onRemove (line 17) | public onRemove(world: ECSWorld): void {
    method onEntityEnter (line 21) | public onEntityEnter(world: ECSWorld, entity: number): void {
    method onEntityLeave (line 25) | public onEntityLeave(world: ECSWorld, entity: number): void {
    method onUpdate (line 35) | public onUpdate(world: ECSWorld, dt: number): void {

FILE: assets/Script/ECS/systems/SysBehaviorTree.ts
  constant FILTER_BEHAVIORTREE (line 8) | const FILTER_BEHAVIORTREE = GenFillterKey([ComBehaviorTree]);
  class SysBehaviorTree (line 12) | class SysBehaviorTree extends ECSSystem {
    method onAdd (line 15) | public onAdd(world: ECSWorld): void{
    method onRemove (line 19) | public onRemove(world: ECSWorld): void {
    method onEntityEnter (line 23) | public onEntityEnter(world: ECSWorld, entity: number): void {
    method onEntityLeave (line 28) | public onEntityLeave(world: ECSWorld, entity: number): void {
    method onUpdate (line 33) | public onUpdate(world: ECSWorld, dt: number): void {
    method onEnterBTNode (line 51) | public onEnterBTNode(node: BT.NodeBase, context: BT.ExecuteContext) {
    method updateBTNode (line 57) | public updateBTNode(node: BT.NodeBase, context: BT.ExecuteContext) {
    method canExecuteBTNode (line 62) | public canExecuteBTNode(node: BT.NodeBase, context: BT.ExecuteContext)...

FILE: assets/Script/ECS/systems/SysCocosView.ts
  type ITouchProcessor (line 10) | interface ITouchProcessor {
  constant FILTER_COCOS_NODE (line 17) | const FILTER_COCOS_NODE = GenFillterKey([ComNodeConfig], [ComCocosNode]);
  constant FILTER_NODE_EVENT (line 18) | const FILTER_NODE_EVENT = GenFillterKey([ComCocosNode, ComTransform]);
  class SysCocosView (line 19) | class SysCocosView extends ECSSystem implements ITouchProcessor {
    method onTouchStart (line 21) | onTouchStart(worldPos: cc.Vec2, world: ECSWorld): boolean {
    method onTouchMove (line 26) | onTouchMove(worldPos: cc.Vec2, world: ECSWorld): void {
    method onTouchCancel (line 30) | onTouchCancel(worldPos: cc.Vec2, world: ECSWorld): void {
    method onAdd (line 34) | onAdd(world: ECSWorld) {
    method onRemove (line 38) | onRemove(world: ECSWorld) {
    method onEntityEnter (line 42) | onEntityEnter(world: ECSWorld, entity: number) {
    method onEntityLeave (line 46) | onEntityLeave(world: ECSWorld, entity: number) {
    method onUpdate (line 50) | onUpdate(world:ECSWorld, dt:number) {
    method _loadView (line 89) | private async _loadView(world: ECSWorld, entity: number, nodeConfig: C...
    method destoryView (line 109) | private destoryView(node: cc.Node) {

FILE: assets/Script/ECS/systems/SysMonitor.ts
  constant FILTER_MONITOR (line 7) | const FILTER_MONITOR = GenFillterKey([ComRoleConfig, ComTransform, ComMo...
  class SysMonitor (line 8) | class SysMonitor extends ECSSystem {
    method onAdd (line 10) | public onAdd(world: ECSWorld): void {
    method onRemove (line 14) | public onRemove(world: ECSWorld): void {
    method onEntityEnter (line 18) | public onEntityEnter(world: ECSWorld, entity: number): void {
    method onEntityLeave (line 22) | public onEntityLeave(world: ECSWorld, entity: number): void {
    method onUpdate (line 37) | public onUpdate(world: ECSWorld, dt: number): void {
  function isInTriangle (line 76) | function isInTriangle(point: cc.Vec2, triA: cc.Vec2, triB: cc.Vec2, triC...

FILE: assets/Script/ECS/systems/SysMovable.ts
  constant FILTER_MOVE (line 7) | const FILTER_MOVE = GenFilterKey([ComMovable, ComTransform, ComCocosNode]);
  class SysMovable (line 8) | class SysMovable extends ECSSystem {
    method onAdd (line 10) | public onAdd(world: ECSWorld): void{
    method onRemove (line 14) | public onRemove(world: ECSWorld): void {
    method onEntityEnter (line 18) | public onEntityEnter(world: ECSWorld, entity: number): void {
    method onEntityLeave (line 23) | public onEntityLeave(world: ECSWorld, entity:number): void {
    method onUpdate (line 28) | public onUpdate(world: ECSWorld, dt:number): void {

FILE: assets/Script/ECS/systems/SysRoleState.ts
  constant FILTER_ROLE_NODE (line 12) | const FILTER_ROLE_NODE = GenFillterKey([ComCocosNode, ComRoleConfig]);
  class SysRoleState (line 13) | class SysRoleState extends ECSSystem {
    method onAdd (line 15) | public onAdd(world: ECSWorld): void {
    method onRemove (line 19) | public onRemove(world: ECSWorld): void {
    method onEntityEnter (line 23) | public onEntityEnter(world: ECSWorld, entity: number): void {
    method onEntityLeave (line 27) | public onEntityLeave(world: ECSWorld, entity: number): void {
    method onUpdate (line 31) | public onUpdate(world: ECSWorld, dt: number): void {

FILE: assets/Script/ECS/worlds/WorldCocosView.ts
  class WorldCocosView (line 3) | class WorldCocosView extends ECSWorld {

FILE: assets/Script/Main.ts
  class Main (line 14) | class Main extends cc.Component {
    method onLoad (line 20) | protected onLoad(): void {
    method start (line 24) | start () {
    method onClick1 (line 42) | onClick1() {
    method onClick2 (line 48) | onClick2() {
    method onClick3 (line 54) | onClick3() {
    method update (line 58) | protected update(dt: number): void {
    method regiestTouchEvent (line 62) | private regiestTouchEvent() {
    method _onTouchStart (line 69) | private _onTouchStart(e: cc.Event.EventTouch) {
    method _onTouchMove (line 74) | private _onTouchMove(e: cc.Event.EventTouch) {
    method _onTouchEnd (line 79) | private _onTouchEnd(e: cc.Event.EventTouch) {
    method _onTouchCancel (line 84) | private _onTouchCancel(e: cc.Event.EventTouch) {
    method regiestTouchHandler (line 90) | public regiestTouchHandler(handler: ITouchProcessor) {
    method unRegiestTouchHandler (line 94) | public unRegiestTouchHandler(handler:ITouchProcessor) {
    method a (line 103) | private a() {

FILE: assets/Script/Struct/Direction.ts
  type Direction (line 1) | enum Direction {

FILE: assets/Script/Struct/NodeEvent.ts
  type EventType (line 1) | enum EventType {
  class EventBase (line 11) | class EventBase {
    method constructor (line 13) | constructor(type:number) {
  class EventStand (line 18) | class EventStand extends EventBase {
    method constructor (line 19) | constructor() {
  class EventRun (line 24) | class EventRun extends EventBase {
    method constructor (line 25) | constructor() {
  class EventAttack (line 30) | class EventAttack extends EventBase {
    method constructor (line 31) | constructor() {
  class EventHurt (line 36) | class EventHurt extends EventBase {
    method constructor (line 37) | constructor() {
  class EventDeath (line 42) | class EventDeath extends EventBase {
    method constructor (line 44) | constructor(cb: Function) {
  class EventHPChange (line 50) | class EventHPChange extends EventBase {
    method constructor (line 54) | constructor(maxHP: number, lastHP: number, nowHP: number) {
  class EventGraphicsDraw (line 62) | class EventGraphicsDraw extends EventBase {
    method constructor (line 65) | constructor(points: cc.Vec2[], color?: cc.Color) {

FILE: creator.d.ts
  class Action (line 1713) | class Action {
  class FiniteTimeAction (line 1766) | class FiniteTimeAction extends Action {
  class ActionInstant (line 1798) | class ActionInstant extends FiniteTimeAction {
  class ActionInterval (line 1813) | class ActionInterval extends FiniteTimeAction {
  class ActionManager (line 1856) | class ActionManager {
  class Tween (line 1982) | class Tween<T = any> {
  class audioEngine (line 2210) | class audioEngine {
  class AnimationClip (line 2610) | class AnimationClip extends Asset {
  class Easing (line 2648) | class Easing {
  class AnimationState (line 2848) | class AnimationState extends Playable {
  class Playable (line 2896) | class Playable {
  type WrapMode (line 2931) | enum WrapMode {
  class debug (line 2942) | class debug {
  class Director (line 3025) | class Director extends EventTarget {
  class Game (line 3259) | class Game extends EventTarget {
  class Node (line 3468) | class Node extends _BaseNode {
  class PrivateNode (line 4330) | class PrivateNode extends Node {
  class Scene (line 4343) | class Scene extends Node {
  class Scheduler (line 4365) | class Scheduler {
  class VideoPlayer (line 4570) | class VideoPlayer extends Component {
  class ParticleAsset (line 4649) | class ParticleAsset extends Asset {
  class ParticleSystem (line 4685) | class ParticleSystem extends RenderComponent implements BlendFunc {
  class TMXLayerInfo (line 4886) | class TMXLayerInfo {
  class TMXImageLayerInfo (line 4892) | class TMXImageLayerInfo {
  class TMXObjectGroupInfo (line 4901) | class TMXObjectGroupInfo {
  class TMXTilesetInfo (line 4914) | class TMXTilesetInfo {
  class TMXMapInfo (line 4939) | class TMXMapInfo {
  class TiledLayer (line 4969) | class TiledLayer extends Component {
  class TiledMap (line 5226) | class TiledMap extends Component {
  class TiledMapAsset (line 5358) | class TiledMapAsset extends Asset {
  class TiledObjectGroup (line 5367) | class TiledObjectGroup extends Component {
  class TiledTile (line 5427) | class TiledTile extends Component {
  class WebView (line 5440) | class WebView extends Component {
  class NodePool (line 5524) | class NodePool {
  class Camera (line 5593) | class Camera extends Component {
  class Light (line 5786) | class Light extends Component {
  class AssetManager (line 5794) | class AssetManager {
  class loader (line 6121) | class loader {
  class url (line 6261) | class url {
  class LoadingItems (line 6269) | class LoadingItems {
  class Asset (line 6287) | class Asset extends Object {
  class macro (line 6355) | class macro {
  class AudioClip (line 6532) | class AudioClip extends Asset implements EventTarget {
  class BitmapFont (line 6632) | class BitmapFont extends Font {
  class BufferAsset (line 6635) | class BufferAsset extends Asset {
  class Font (line 6639) | class Font extends Asset {
  class JsonAsset (line 6650) | class JsonAsset extends Asset {
  class LabelAtlas (line 6656) | class LabelAtlas extends BitmapFont {
  class Prefab (line 6660) | class Prefab extends Asset {
  class RenderTexture (line 6681) | class RenderTexture extends Texture2D {
  class SceneAsset (line 6712) | class SceneAsset extends Asset {
  class _Script (line 6720) | class _Script extends Asset {
  class _JavaScript (line 6724) | class _JavaScript extends Asset {
  class TypeScript (line 6728) | class TypeScript extends Asset {
  class SpriteAtlas (line 6732) | class SpriteAtlas extends Asset {
  class SpriteFrame (line 6756) | class SpriteFrame extends Asset implements EventTarget {
  class TTFFont (line 6995) | class TTFFont extends Font {
  class TextAsset (line 6999) | class TextAsset extends Asset {
  class Texture2D (line 7004) | class Texture2D extends Asset implements EventTarget {
  class BoxCollider (line 7245) | class BoxCollider extends Collider implements Collider.Box {
  class CircleCollider (line 7260) | class CircleCollider extends Collider implements Collider.Circle {
  class Collider (line 7275) | class Collider extends Component {
  class ColliderInfo (line 7284) | class ColliderInfo {
  class CollisionManager (line 7321) | class CollisionManager implements EventTarget {
  class Intersection (line 7430) | class Intersection {
  class PolygonCollider (line 7510) | class PolygonCollider extends Collider implements Collider.Polygon {
  class Touch (line 7525) | class Touch {
  class EventTarget (line 7607) | class EventTarget extends CallbacksInvoker {
  class Event (line 7704) | class Event {
  class SystemEvent (line 7815) | class SystemEvent extends EventTarget {
  class Animation (line 7848) | class Animation extends Component implements EventTarget {
  class AudioSource (line 8059) | class AudioSource extends Component {
  class BlockInputEvents (line 8133) | class BlockInputEvents extends Component {
  class Button (line 8190) | class Button extends Component implements GraySpriteState {
  class Canvas (line 8259) | class Canvas extends Component {
  class Component (line 8282) | class Component extends Object {
  class Label (line 8540) | class Label extends RenderComponent {
  class LabelOutline (line 8600) | class LabelOutline extends Component {
  class LabelShadow (line 8610) | class LabelShadow extends Component {
  class Layout (line 8632) | class Layout extends Component {
  class Mask (line 8697) | class Mask extends RenderComponent {
  class MotionStreak (line 8733) | class MotionStreak extends Component implements BlendFunc {
  class PageView (line 8775) | class PageView extends ScrollView {
  class PageViewIndicator (line 8864) | class PageViewIndicator extends Component {
  class ProgressBar (line 8889) | class ProgressBar extends Component {
  class RenderComponent (line 8910) | class RenderComponent extends Component {
  class RichText (line 8935) | class RichText extends Component {
  class SafeArea (line 8987) | class SafeArea extends Component {
  class Scrollbar (line 9003) | class Scrollbar extends Component {
  class ScrollView (line 9027) | class ScrollView extends Component {
  class Slider (line 9278) | class Slider extends Component {
  class Sprite (line 9294) | class Sprite extends RenderComponent implements BlendFunc {
  class Toggle (line 9346) | class Toggle extends Button implements GraySpriteState {
  class ToggleContainer (line 9385) | class ToggleContainer extends Component {
  class ToggleGroup (line 9402) | class ToggleGroup extends Component {
  class ViewGroup (line 9423) | class ViewGroup extends Component {
  class Widget (line 9432) | class Widget extends Component {
  class SubContextView (line 9580) | class SubContextView extends Component {
  class WXSubContextView (line 9594) | class WXSubContextView extends Component {
  class SwanSubContextView (line 9598) | class SwanSubContextView extends Component {
  class Mesh (line 9602) | class Mesh extends Asset implements EventTarget {
  class MeshRenderer (line 9767) | class MeshRenderer extends RenderComponent {
  class BufferRange (line 9790) | class BufferRange {
  class VertexFormat (line 9797) | class VertexFormat {
  class Graphics (line 9814) | class Graphics extends RenderComponent {
  class path (line 9959) | class path {
  class AffineTransform (line 10056) | class AffineTransform {
  class _BaseNode (line 10162) | class _BaseNode extends Object implements EventTarget {
  class BlendFunc (line 10576) | class BlendFunc {
  class GraySpriteState (line 10585) | class GraySpriteState {
  class misc (line 10594) | class misc {
  class renderer (line 10657) | class renderer {
  class constructor (line 10670) | class constructor {
  type VerticalTextAlignment (line 10683) | enum VerticalTextAlignment {
  class Object (line 10689) | class Object {
  type Flags (line 10723) | enum Flags {
  class sys (line 10729) | class sys {
  class screen (line 10933) | class screen {
  class View (line 10970) | class View extends EventTarget {
  class ContainerStrategy (line 11262) | class ContainerStrategy {
  class ContentStrategy (line 11288) | class ContentStrategy {
  class EqualToFrame (line 11314) | class EqualToFrame extends ContainerStrategy {
  class ProportionalToFrame (line 11317) | class ProportionalToFrame extends ContainerStrategy {
  class EqualToWindow (line 11320) | class EqualToWindow extends EqualToFrame {
  class ProportionalToWindow (line 11323) | class ProportionalToWindow extends ProportionalToFrame {
  class OriginalContainer (line 11326) | class OriginalContainer extends ContainerStrategy {
  class ResolutionPolicy (line 11330) | class ResolutionPolicy {
  class visibleRect (line 11396) | class visibleRect {
  class CallbacksInvoker (line 11427) | class CallbacksInvoker {
  class Details (line 11478) | class Details {
  class WorldManifold (line 11514) | class WorldManifold {
  class ManifoldPoint (line 11534) | class ManifoldPoint {
  class Manifold (line 11558) | class Manifold {
  class PhysicsImpulse (line 11594) | class PhysicsImpulse {
  class PhysicsContact (line 11612) | class PhysicsContact {
  class PhysicsManager (line 11736) | class PhysicsManager implements EventTarget {
  class PhysicsRayCastResult (line 11909) | class PhysicsRayCastResult {
  type RigidBodyType (line 11933) | enum RigidBodyType {
  type RayCastType (line 11941) | enum RayCastType {
  class RigidBody (line 11948) | class RigidBody extends Component {
  class Color (line 12282) | class Color extends ValueType {
  class Mat3 (line 12640) | class Mat3 extends ValueType {
  class Mat4 (line 12662) | class Mat4 extends ValueType {
  class Quat (line 13055) | class Quat extends ValueType {
  class Rect (line 13333) | class Rect extends ValueType {
  class Size (line 13527) | class Size {
  class ValueType (line 13596) | class ValueType {
  class Vec2 (line 13635) | class Vec2 extends ValueType {
  class Vec3 (line 14212) | class Vec3 extends ValueType {
  class Vec4 (line 14747) | class Vec4 extends ValueType {
  class SkeletonAnimation (line 15154) | class SkeletonAnimation extends Animation {
  class SkeletonAnimationClip (line 15158) | class SkeletonAnimationClip extends AnimationClip {
  class SkinnedMeshRenderer (line 15164) | class SkinnedMeshRenderer extends MeshRenderer {
  class AnimationCurve (line 15178) | class AnimationCurve {
  class Burst (line 15191) | class Burst {
  class ParticleSystem3D (line 15213) | class ParticleSystem3D extends RenderComponent {
  class MapUtils (line 15344) | class MapUtils {
  class EffectAsset (line 15348) | class EffectAsset extends Asset {
  class Material (line 15352) | class Material extends Asset {
  class MaterialVariant (line 15466) | class MaterialVariant extends Material {
  class EditBox (line 15482) | class EditBox extends Component {
  class PhysicsBoxCollider (line 15596) | class PhysicsBoxCollider extends PhysicsCollider implements Collider.Box {
  class PhysicsChainCollider (line 15605) | class PhysicsChainCollider extends PolygonCollider {
  class PhysicsCircleCollider (line 15614) | class PhysicsCircleCollider extends PhysicsCollider implements Collider....
  class PhysicsCollider (line 15623) | class PhysicsCollider extends Collider {
  class PhysicsPolygonCollider (line 15665) | class PhysicsPolygonCollider extends PhysicsCollider implements Collider...
  class DistanceJoint (line 15679) | class DistanceJoint extends Joint {
  class Joint (line 15700) | class Joint extends Component {
  class MotorJoint (line 15766) | class MotorJoint extends Joint {
  class MouseJoint (line 15816) | class MouseJoint extends Joint {
  class PrismaticJoint (line 15864) | class PrismaticJoint extends Joint {
  class RevoluteJoint (line 15917) | class RevoluteJoint extends Joint {
  class RopeJoint (line 15971) | class RopeJoint extends Joint {
  class WeldJoint (line 15984) | class WeldJoint extends Joint {
  class WheelJoint (line 16010) | class WheelJoint extends Joint {
  type ERigidBodyType (line 16044) | enum ERigidBodyType {
  class ITriggerEvent (line 16053) | class ITriggerEvent {
  class IContactEquation (line 16074) | class IContactEquation {
  class ICollisionEvent (line 16095) | class ICollisionEvent {
  class Physics3DManager (line 16121) | class Physics3DManager {
  class PhysicsRayResult (line 16188) | class PhysicsRayResult {
  class ShapeModule (line 16224) | class ShapeModule {
  class ColorOvertimeModule (line 16292) | class ColorOvertimeModule {
  class CurveRange (line 16299) | class CurveRange {
  class ForceOvertimeModule (line 16327) | class ForceOvertimeModule {
  class GradientRange (line 16346) | class GradientRange {
  class ColorKey (line 16371) | class ColorKey {
  class AlphaKey (line 16381) | class AlphaKey {
  class Gradient (line 16391) | class Gradient {
  class LimitVelocityOvertimeModule (line 16404) | class LimitVelocityOvertimeModule {
  class OptimizedCurve (line 16432) | class OptimizedCurve {
  class RotationOvertimeModule (line 16436) | class RotationOvertimeModule {
  class SizeOvertimeModule (line 16455) | class SizeOvertimeModule {
  class TextureAnimationModule (line 16477) | class TextureAnimationModule {
  class VelocityOvertimeModule (line 16515) | class VelocityOvertimeModule {
  class IRigidBody (line 16536) | class IRigidBody {
  class IVec3Like (line 16608) | class IVec3Like {
  class IQuatLike (line 16614) | class IQuatLike {
  class IBaseShape (line 16621) | class IBaseShape {
  class IBoxShape (line 16629) | class IBoxShape {
  class ISphereShape (line 16633) | class ISphereShape {
  class IRaycastOptions (line 16637) | class IRaycastOptions {
  class ICollisionDetect (line 16643) | class ICollisionDetect {
  class IPhysicsWorld (line 16661) | class IPhysicsWorld {
  class TrailModule (line 16665) | class TrailModule {
  class DynamicAtlasManager (line 16705) | class DynamicAtlasManager {
  class PhysicsMaterial (line 16749) | class PhysicsMaterial extends Asset {
  class ConstantForce (line 16765) | class ConstantForce extends Component {
  class RigidBody3D (line 16791) | class RigidBody3D extends Component {
  class BoxCollider3D (line 16960) | class BoxCollider3D extends Collider3D {
  class Collider3D (line 16972) | class Collider3D extends Component implements EventTarget {
  class SphereCollider3D (line 17092) | class SphereCollider3D extends Collider3D {
  type AudioState (line 17107) | enum AudioState {
  type DebugMode (line 17123) | enum DebugMode {
  type _LocalDirtyFlag (line 17141) | enum _LocalDirtyFlag {
  class EventType (line 17169) | class EventType {
  type EventType (line 17261) | enum EventType {
  type ResourceType (line 17279) | enum ResourceType {
  type EmitterMode (line 17292) | enum EmitterMode {
  type PositionType (line 17305) | enum PositionType {
  type Orientation (line 17319) | enum Orientation {
  type Property (line 17332) | enum Property {
  type TileFlag (line 17348) | enum TileFlag {
  type StaggerAxis (line 17364) | enum StaggerAxis {
  type RenderOrder (line 17377) | enum RenderOrder {
  type TMXObjectType (line 17394) | enum TMXObjectType {
  type EventType (line 17411) | enum EventType {
  type ClearFlags (line 17425) | enum ClearFlags {
  type Type (line 17440) | enum Type {
  type ShadowType (line 17456) | enum ShadowType {
  type OptimizationPolicy (line 17474) | enum OptimizationPolicy {
  type DepthStencilFormat (line 17488) | enum DepthStencilFormat {
  type PixelFormat (line 17503) | enum PixelFormat {
  type WrapMode (line 17532) | enum WrapMode {
  type Filter (line 17545) | enum Filter {
  class Box (line 17558) | class Box {
  class Circle (line 17575) | class Circle {
  class Polygon (line 17592) | class Polygon {
  class EventMouse (line 17609) | class EventMouse extends Event {
  class EventTouch (line 17734) | class EventTouch extends Event {
  class EventAcceleration (line 17821) | class EventAcceleration extends Event {
  class EventKeyboard (line 17832) | class EventKeyboard extends Event {
  class EventCustom (line 17853) | class EventCustom extends Event {
  class EventType (line 17889) | class EventType {
  class EventType (line 17909) | class EventType {
  type Transition (line 17938) | enum Transition {
  class EventHandler (line 17959) | class EventHandler {
  type HorizontalAlign (line 18004) | enum HorizontalAlign {
  type VerticalAlign (line 18018) | enum VerticalAlign {
  type Overflow (line 18032) | enum Overflow {
  type Type (line 18047) | enum Type {
  type CacheMode (line 18061) | enum CacheMode {
  type Type (line 18075) | enum Type {
  type ResizeMode (line 18090) | enum ResizeMode {
  type AxisDirection (line 18105) | enum AxisDirection {
  type VerticalDirection (line 18119) | enum VerticalDirection {
  type HorizontalDirection (line 18133) | enum HorizontalDirection {
  type Type (line 18146) | enum Type {
  type SizeMode (line 18160) | enum SizeMode {
  type Direction (line 18173) | enum Direction {
  type EventType (line 18186) | enum EventType {
  type Direction (line 18198) | enum Direction {
  type Mode (line 18211) | enum Mode {
  type Direction (line 18224) | enum Direction {
  type EventType (line 18237) | enum EventType {
  type Direction (line 18261) | enum Direction {
  type Type (line 18274) | enum Type {
  type FillType (line 18290) | enum FillType {
  type SizeMode (line 18304) | enum SizeMode {
  type State (line 18318) | enum State {
  type AlignMode (line 18331) | enum AlignMode {
  class Aabb (line 18344) | class Aabb {
  type enums (line 18411) | enum enums {
  class Frustum (line 18431) | class Frustum {
  class intersect (line 18472) | class intersect {
  class Line (line 18683) | class Line {
  class Obb (line 18774) | class Obb {
  class Plane (line 18915) | class Plane {
  class Ray (line 19016) | class Ray {
  class Sphere (line 19099) | class Sphere {
  class Triangle (line 19210) | class Triangle {
  type ShadowCastingMode (line 19271) | enum ShadowCastingMode {
  type LineCap (line 19284) | enum LineCap {
  type LineJoin (line 19298) | enum LineJoin {
  type KEY (line 19312) | enum KEY {
  type ImageFormat (line 19423) | enum ImageFormat {
  type BlendFactor (line 19449) | enum BlendFactor {
  type TextAlignment (line 19469) | enum TextAlignment {
  type NetworkType (line 19485) | enum NetworkType {
  type DrawBits (line 19519) | enum DrawBits {
  type WrapMode (line 19533) | enum WrapMode {
  type Space (line 19552) | enum Space {
  type RenderMode (line 19562) | enum RenderMode {
  type ShapeType (line 19572) | enum ShapeType {
  type EmitLocation (line 19587) | enum EmitLocation {
  type ArcMode (line 19601) | enum ArcMode {
  type TrailMode (line 19614) | enum TrailMode {
  type TextureMode (line 19624) | enum TextureMode {
  type PolyhedronType (line 19634) | enum PolyhedronType {
  class VertexData (line 19659) | class VertexData {
  type BUILTIN_NAME (line 19677) | enum BUILTIN_NAME {
  type KeyboardReturnType (line 19691) | enum KeyboardReturnType {
  type InputMode (line 19708) | enum InputMode {
  type InputFlag (line 19726) | enum InputFlag {
  type Mode (line 19742) | enum Mode {
  type Animation (line 19752) | enum Animation {
  class Skeleton (line 19777) | class Skeleton extends cc.RenderComponent {
  class SkeletonData (line 20139) | class SkeletonData extends cc.Asset {
  type AnimationEventType (line 20166) | enum AnimationEventType {
  class VertexEffectDelegate (line 20176) | class VertexEffectDelegate {
  class AttachUtil (line 20231) | class AttachUtil {
  type AnimationCacheMode (line 20275) | enum AnimationCacheMode {
  class ArmatureDisplay (line 20311) | class ArmatureDisplay extends cc.RenderComponent {
  class CCFactory (line 20511) | class CCFactory extends BaseFactory {
  class DragonBonesAsset (line 20524) | class DragonBonesAsset extends cc.Asset {
  class DragonBonesAtlasAsset (line 20531) | class DragonBonesAtlasAsset extends cc.Asset {
  type AnimationCacheMode (line 20542) | enum AnimationCacheMode {
  class AttachUtil (line 20556) | class AttachUtil {
  class Builtins (line 20607) | class Builtins {
  class Bundle (line 20646) | class Bundle {
  class CacheManager (line 20998) | class CacheManager {
  class Cache (line 21083) | class Cache<T = any> {
  class DependUtil (line 21218) | class DependUtil {
  class Downloader (line 21279) | class Downloader {
  class Helper (line 21350) | class Helper {
  class PackManager (line 21424) | class PackManager {
  class Parser (line 21507) | class Parser {
  class Pipeline (line 21551) | class Pipeline {
  class RequestItem (line 21700) | class RequestItem {
  type BuiltinBundleName (line 21785) | enum BuiltinBundleName {
  class Task (line 21796) | class Task {
  class array (line 22461) | class array {
  class Pool (line 22526) | class Pool {
  type FlagExcludedType (line 22665) | type FlagExcludedType<Base, Type> = { [Key in keyof Base]: Base[Key] ext...
  type AllowedNames (line 22666) | type AllowedNames<Base, Type> = FlagExcludedType<Base, Type>[keyof Base];
  type KeyPartial (line 22667) | type KeyPartial<T, K extends keyof T> = { [P in K]?: T[P] };
  type OmitType (line 22668) | type OmitType<Base, Type> = KeyPartial<Base, AllowedNames<Base, Type>>;
  type ConstructorType (line 22669) | type ConstructorType<T> = OmitType<T, Function>;
  type IWritableArrayLike (line 22671) | interface IWritableArrayLike<T> {
  type Math (line 22681) | interface Math {
  type Object (line 22685) | interface Object {
  type FloatArray (line 22690) | type FloatArray = Float64Array | Float32Array;
  type IColorLike (line 22692) | interface IColorLike {
  type IMat3Like (line 22701) | interface IMat3Like {
  type IMat4Like (line 22705) | interface IMat4Like {
  type IQuatLike (line 22709) | interface IQuatLike {
  type IRectLike (line 22716) | interface IRectLike {
  type ISizeLike (line 22723) | interface ISizeLike {
  type IVec2Like (line 22728) | interface IVec2Like {
  type IVec3Like (line 22733) | interface IVec3Like {
  type IVec4Like (line 22739) | interface IVec4Like {
  type BinaryOffset (line 22784) | const enum BinaryOffset {
  type ArmatureType (line 22813) | const enum ArmatureType {
  type BoneType (line 22822) | const enum BoneType {
  type DisplayType (line 22829) | const enum DisplayType {
  type BoundingBoxType (line 22845) | const enum BoundingBoxType {
  type ActionType (line 22854) | const enum ActionType {
  type BlendMode (line 22863) | const enum BlendMode {
  type TweenType (line 22883) | const enum TweenType {
  type TimelineType (line 22895) | const enum TimelineType {
  type OffsetMode (line 22920) | const enum OffsetMode {
  type AnimationFadeOutMode (line 22935) | const enum AnimationFadeOutMode {
  type Map (line 22994) | interface Map<T> {
  class DragonBones (line 23000) | class DragonBones {
  class Matrix (line 23165) | class Matrix {
  class Transform (line 23360) | class Transform {
  class ColorTransform (line 23513) | class ColorTransform {
  class Point (line 23560) | class Point {
  class Rectangle (line 23653) | class Rectangle {
  class UserData (line 23753) | class UserData extends BaseObject {
  class ActionData (line 23845) | class ActionData extends BaseObject {
  class DragonBonesData (line 23892) | class DragonBonesData extends BaseObject {
  class ArmatureData (line 24069) | class ArmatureData extends BaseObject {
  class BoneData (line 24316) | class BoneData extends BaseObject {
  class SurfaceData (line 24388) | class SurfaceData extends BoneData {
  class SlotData (line 24408) | class SlotData extends BaseObject {
  class IKConstraintData (line 24507) | class IKConstraintData extends ConstraintData {
  class CanvasData (line 24542) | class CanvasData extends BaseObject {
  class SkinData (line 24586) | class SkinData extends BaseObject {
  class ImageDisplayData (line 24665) | class ImageDisplayData extends DisplayData {
  class ArmatureDisplayData (line 24675) | class ArmatureDisplayData extends DisplayData {
  class MeshDisplayData (line 24690) | class MeshDisplayData extends DisplayData {
  class BoundingBoxDisplayData (line 24703) | class BoundingBoxDisplayData extends DisplayData {
  class WeightData (line 24712) | class WeightData extends BaseObject {
  class GlueData (line 24724) | class GlueData extends BaseObject {
  class RectangleBoundingBoxData (line 24841) | class RectangleBoundingBoxData extends BoundingBoxData {
  class EllipseBoundingBoxData (line 24893) | class EllipseBoundingBoxData extends BoundingBoxData {
  class PolygonBoundingBoxData (line 24941) | class PolygonBoundingBoxData extends BoundingBoxData {
  class AnimationData (line 25036) | class AnimationData extends BaseObject {
  class TimelineData (line 25225) | class TimelineData extends BaseObject {
  class AnimationConfig (line 25272) | class AnimationConfig extends BaseObject {
  type IArmatureProxy (line 25681) | interface IArmatureProxy extends IEventDispatcher {
  class Armature (line 25783) | class Armature extends BaseObject implements IAnimatable {
  class Bone (line 26516) | class Bone extends TransformObject {
  class Surface (line 26736) | class Surface extends Bone {
  class IKConstraint (line 27408) | class IKConstraint extends Constraint {
  type IAnimatable (line 27468) | interface IAnimatable {
  class WorldClock (line 27542) | class WorldClock implements IAnimatable {
  class Animation (line 27701) | class Animation extends BaseObject {
  class AnimationState (line 28178) | class AnimationState extends BaseObject {
  class BonePose (line 28610) | class BonePose extends BaseObject {
  class BlendState (line 28621) | class BlendState {
  type TweenState (line 28658) | const enum TweenState {
  class ActionTimelineState (line 28772) | class ActionTimelineState extends TimelineState {
  class ZOrderTimelineState (line 28784) | class ZOrderTimelineState extends TimelineState {
  class BoneAllTimelineState (line 28793) | class BoneAllTimelineState extends BoneTimelineState {
  class BoneTranslateTimelineState (line 28803) | class BoneTranslateTimelineState extends BoneTimelineState {
  class BoneRotateTimelineState (line 28812) | class BoneRotateTimelineState extends BoneTimelineState {
  class BoneScaleTimelineState (line 28822) | class BoneScaleTimelineState extends BoneTimelineState {
  class SurfaceTimelineState (line 28831) | class SurfaceTimelineState extends TweenTimelineState {
  class SlotDislayTimelineState (line 28851) | class SlotDislayTimelineState extends SlotTimelineState {
  class SlotColorTimelineState (line 28859) | class SlotColorTimelineState extends SlotTimelineState {
  class SlotFFDTimelineState (line 28875) | class SlotFFDTimelineState extends SlotTimelineState {
  class IKConstraintTimelineState (line 28897) | class IKConstraintTimelineState extends ConstraintTimelineState {
  class AnimationTimelineState (line 28909) | class AnimationTimelineState extends TweenTimelineState {
  class EventObject (line 28953) | class EventObject extends BaseObject {
  type EventStringType (line 29184) | type EventStringType = string | "start" | "loopComplete" | "complete" | ...
  type IEventDispatcher (line 29197) | interface IEventDispatcher {
  class ObjectDataParser (line 29499) | class ObjectDataParser extends DataParser {
  class ActionFrame (line 29594) | class ActionFrame {
  class BinaryDataParser (line 29626) | class BinaryDataParser extends ObjectDataParser {
  class BuildArmaturePackage (line 30214) | class BuildArmaturePackage {
  class Animation (line 30224) | class Animation {
  type Timeline (line 30235) | interface Timeline {
  type MixBlend (line 30239) | enum MixBlend {
  type MixDirection (line 30245) | enum MixDirection {
  type TimelineType (line 30249) | enum TimelineType {
  class RotateTimeline (line 30282) | class RotateTimeline extends CurveTimeline {
  class TranslateTimeline (line 30294) | class TranslateTimeline extends CurveTimeline {
  class ScaleTimeline (line 30308) | class ScaleTimeline extends TranslateTimeline {
  class ShearTimeline (line 30313) | class ShearTimeline extends TranslateTimeline {
  class ColorTimeline (line 30318) | class ColorTimeline extends CurveTimeline {
  class TwoColorTimeline (line 30336) | class TwoColorTimeline extends CurveTimeline {
  class AttachmentTimeline (line 30360) | class AttachmentTimeline implements Timeline {
  class DeformTimeline (line 30370) | class DeformTimeline extends CurveTimeline {
  class EventTimeline (line 30380) | class EventTimeline implements Timeline {
  class DrawOrderTimeline (line 30389) | class DrawOrderTimeline implements Timeline {
  class IkConstraintTimeline (line 30398) | class IkConstraintTimeline extends CurveTimeline {
  class TransformConstraintTimeline (line 30418) | class TransformConstraintTimeline extends CurveTimeline {
  class PathConstraintPositionTimeline (line 30436) | class PathConstraintPositionTimeline extends CurveTimeline {
  class PathConstraintSpacingTimeline (line 30448) | class PathConstraintSpacingTimeline extends PathConstraintPositionTimeli...
  class PathConstraintMixTimeline (line 30453) | class PathConstraintMixTimeline extends CurveTimeline {
  class AnimationState (line 30469) | class AnimationState {
  class TrackEntry (line 30514) | class TrackEntry {
  class EventQueue (line 30551) | class EventQueue {
  type EventType (line 30565) | enum EventType {
  type AnimationStateListener (line 30573) | interface AnimationStateListener {
  class AnimationStateData (line 30591) | class AnimationStateData {
  class AssetManager (line 30602) | class AssetManager implements Disposable {
  class AtlasAttachmentLoader (line 30629) | class AtlasAttachmentLoader implements AttachmentLoader {
  type BlendMode (line 30641) | enum BlendMode {
  class Bone (line 30649) | class Bone implements Updatable {
  class BoneData (line 30696) | class BoneData {
  type TransformMode (line 30713) | enum TransformMode {
  class Event (line 30730) | class Event {
  class EventData (line 30742) | class EventData {
  class IkConstraint (line 30754) | class IkConstraint implements Updatable {
  class IkConstraintData (line 30773) | class IkConstraintData extends ConstraintData {
  class PathConstraint (line 30786) | class PathConstraint implements Updatable {
  class PathConstraintData (line 30816) | class PathConstraintData extends ConstraintData {
  type PositionMode (line 30829) | enum PositionMode {
  type SpacingMode (line 30833) | enum SpacingMode {
  type RotateMode (line 30838) | enum RotateMode {
  class SharedAssetManager (line 30845) | class SharedAssetManager implements Disposable {
  class Skeleton (line 30865) | class Skeleton {
  class SkeletonBinary (line 30913) | class SkeletonBinary {
  class SkeletonBounds (line 30949) | class SkeletonBounds {
  class SkeletonClipping (line 30972) | class SkeletonClipping {
  class SkeletonData (line 30991) | class SkeletonData {
  class SkeletonJson (line 31025) | class SkeletonJson {
  class SkinEntry (line 31044) | class SkinEntry {
  class Skin (line 31050) | class Skin {
  class Slot (line 31068) | class Slot {
  class SlotData (line 31086) | class SlotData {
  type TextureFilter (line 31108) | enum TextureFilter {
  type TextureWrap (line 31117) | enum TextureWrap {
  class TextureRegion (line 31122) | class TextureRegion {
  class FakeTexture (line 31136) | class FakeTexture extends Texture {
  class TextureAtlas (line 31143) | class TextureAtlas implements Disposable {
  class TextureAtlasPage (line 31151) | class TextureAtlasPage {
  class TextureAtlasRegion (line 31161) | class TextureAtlasRegion extends TextureRegion {
  class TransformConstraint (line 31173) | class TransformConstraint implements Updatable {
  class TransformConstraintData (line 31194) | class TransformConstraintData extends ConstraintData {
  class Triangulator (line 31213) | class Triangulator {
  type Updatable (line 31229) | interface Updatable {
  type Map (line 31235) | interface Map<T> {
  class IntSet (line 31238) | class IntSet {
  type Disposable (line 31245) | interface Disposable {
  type Restorable (line 31248) | interface Restorable {
  class Color (line 31251) | class Color {
  class MathUtils (line 31270) | class MathUtils {
  class Pow (line 31290) | class Pow extends Interpolation {
  class PowOut (line 31295) | class PowOut extends Pow {
  class Utils (line 31299) | class Utils {
  class DebugUtils (line 31312) | class DebugUtils {
  class Pool (line 31315) | class Pool<T> {
  class Vector2 (line 31324) | class Vector2 {
  class TimeKeeper (line 31332) | class TimeKeeper {
  type ArrayLike (line 31342) | interface ArrayLike<T> {
  class WindowedMean (line 31346) | class WindowedMean {
  type VertexEffect (line 31359) | interface VertexEffect {
  type Math (line 31365) | interface Math {
  type AttachmentLoader (line 31387) | interface AttachmentLoader {
  type AttachmentType (line 31397) | enum AttachmentType {
  class BoundingBoxAttachment (line 31408) | class BoundingBoxAttachment extends VertexAttachment {
  class ClippingAttachment (line 31415) | class ClippingAttachment extends VertexAttachment {
  class MeshAttachment (line 31423) | class MeshAttachment extends VertexAttachment {
  class PathAttachment (line 31445) | class PathAttachment extends VertexAttachment {
  class PointAttachment (line 31455) | class PointAttachment extends VertexAttachment {
  class RegionAttachment (line 31467) | class RegionAttachment extends Attachment {
  class JitterEffect (line 31530) | class JitterEffect implements VertexEffect {
  class SwirlEffect (line 31540) | class SwirlEffect implements VertexEffect {
  type DownloaderTask (line 31576) | type DownloaderTask = { requestURL: string, storagePath: string, identif...
  class Downloader (line 31581) | class Downloader{
  type ManifestAsset (line 31598) | interface ManifestAsset {
  class Manifest (line 31606) | class Manifest {
  class EventAssetsManager (line 31625) | class EventAssetsManager {
  type State (line 31659) | enum State {
  class AssetsManager (line 31677) | class AssetsManager {
Condensed preview — 227 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,600K chars).
[
  {
    "path": ".gitignore",
    "chars": 1294,
    "preview": "#/////////////////////////////////////////////////////////////////////////////\n# Fireball Projects\n#////////////////////"
  },
  {
    "path": "BehaviorTree.dio",
    "chars": 3163,
    "preview": "<mxfile host=\"65bd71144e\">\n    <diagram id=\"dLwbfvz9vYh7qeJd_Tvh\" name=\"第 1 页\">\n        <mxGraphModel dx=\"647\" dy=\"612\" "
  },
  {
    "path": "ECS.dio",
    "chars": 12586,
    "preview": "<mxfile host=\"65bd71144e\">\n    <diagram id=\"TQPzfji1_PItH667R2By\" name=\"第 1 页\">\n        <mxGraphModel dx=\"783\" dy=\"741\" "
  },
  {
    "path": "LICENSE",
    "chars": 1064,
    "preview": "MIT License\n\nCopyright (c) 2024 honmono\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof"
  },
  {
    "path": "README.md",
    "chars": 13214,
    "preview": "# 在Cocos中使用ECS + BehaviorTree 实现格斗AI  使用过程中有任何问题,可以加QQ群: 552424835\n### 成品展示\n\ndemo 角色AI包含了巡逻, 追踪, 攻击, 躲避攻击, 受伤打断攻击, 攻击打断闪"
  },
  {
    "path": "assets/Scene/helloworld.fire",
    "chars": 30266,
    "preview": "[\n  {\n    \"__type__\": \"cc.SceneAsset\",\n    \"_name\": \"\",\n    \"_objFlags\": 0,\n    \"_native\": \"\",\n    \"scene\": {\n      \"__i"
  },
  {
    "path": "assets/Scene/helloworld.fire.meta",
    "chars": 169,
    "preview": "{\n  \"ver\": \"1.3.2\",\n  \"uuid\": \"2d2f792f-a40c-49bb-a189-ed176a246e49\",\n  \"importer\": \"scene\",\n  \"asyncLoadAssets\": false,"
  },
  {
    "path": "assets/Scene.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"29f52784-2fca-467b-92e7-8fd9ef8c57b7\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/Script/Common/BehaviorTree.ts",
    "chars": 28797,
    "preview": "import { ComAttackable } from \"../ECS/components/ComAttackable\";\nimport { ComBeAttacked } from \"../ECS/components/ComBeA"
  },
  {
    "path": "assets/Script/Common/BehaviorTree.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"6cd218b5-3651-451d-90b5-5765b038f824\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/Common/CocosHelper.ts",
    "chars": 10183,
    "preview": "export class LoadProgress {\n    public url: string;\n    public completedCount: number;\n    public totalCount: number;\n  "
  },
  {
    "path": "assets/Script/Common/CocosHelper.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"dc730152-9513-4cfe-b6f9-8d6cfdfc0e23\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/Common/FrameAnimation.ts",
    "chars": 2188,
    "preview": "const {ccclass, property} = cc._decorator;\n\n@ccclass('FrameConfig')\nclass FrameConfig {\n    @property(cc.Integer) frames"
  },
  {
    "path": "assets/Script/Common/FrameAnimation.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"60f21b10-95a9-4650-83ae-ff5522171c04\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/Common.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"07d0024f-7d77-45fb-84e1-676ae4645108\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/Script/Core/ECSController.ts",
    "chars": 3667,
    "preview": "import { BT } from \"../Common/BehaviorTree\";\nimport { ComAttackable } from \"../ECS/components/ComAttackable\";\nimport { C"
  },
  {
    "path": "assets/Script/Core/ECSController.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"f4905a62-50f2-4508-8932-c2446dc9ee16\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/Core/EventProcess.ts",
    "chars": 348,
    "preview": "import { EventBase } from \"../Struct/NodeEvent\";\n\nconst {ccclass, property} = cc._decorator;\n\n@ccclass\nexport class Even"
  },
  {
    "path": "assets/Script/Core/EventProcess.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"421fe0f3-34ce-4d96-8ede-370f051cdb61\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/Core/RoleEventProcess.ts",
    "chars": 3367,
    "preview": "import CocosHelper from \"../Common/CocosHelper\";\nimport { EventBase, EventDeath, EventGraphicsDraw, EventHPChange, Event"
  },
  {
    "path": "assets/Script/Core/RoleEventProcess.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"d38f8101-a4d4-422a-95ce-643759bfe803\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/Core.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"5e76ac49-9cf7-4eba-9b00-da0cbbdf8778\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/Script/ECS/components/ComAttackable.ts",
    "chars": 715,
    "preview": "import { ComType, EntityIndex } from \"../lib/Const\";\nimport { ECSComponent } from \"../lib/ECSComponent\";\n\n@ECSComponent("
  },
  {
    "path": "assets/Script/ECS/components/ComAttackable.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"7ee555b4-eed0-4207-81f5-41b51bb3bd73\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/components/ComBeAttacked.ts",
    "chars": 212,
    "preview": "import { ComType, EntityIndex } from \"../lib/Const\";\nimport { ECSComponent } from \"../lib/ECSComponent\";\n\n@ECSComponent("
  },
  {
    "path": "assets/Script/ECS/components/ComBeAttacked.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"c3d913ea-e619-4f5e-bb18-3fe947505dda\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/components/ComBehaviorTree.ts",
    "chars": 301,
    "preview": "import { BT } from \"../../Common/BehaviorTree\";\nimport { ComType } from \"../lib/Const\";\nimport { ECSComponent } from \".."
  },
  {
    "path": "assets/Script/ECS/components/ComBehaviorTree.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"a529fff3-0126-4e53-a4c7-e5ddb6d76976\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/components/ComCocosNode.ts",
    "chars": 307,
    "preview": "import { EventBase } from \"../../Struct/NodeEvent\";\nimport { ComType } from \"../lib/Const\";\nimport { ECSComponent } from"
  },
  {
    "path": "assets/Script/ECS/components/ComCocosNode.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"e75ab1ce-3260-45cb-975a-9c4c1ab72f94\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/components/ComMonitor.ts",
    "chars": 332,
    "preview": "import { ComType, EntityIndex } from \"../lib/Const\";\nimport { ECSComponent } from \"../lib/ECSComponent\";\n\n@ECSComponent("
  },
  {
    "path": "assets/Script/ECS/components/ComMonitor.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"274fabed-397f-4950-b691-2c6b6b894c9f\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/components/ComMovable.ts",
    "chars": 323,
    "preview": "import { ComType } from \"../lib/Const\";\nimport { ECSComponent } from \"../lib/ECSComponent\";\n\n@ECSComponent(ComType.ComMo"
  },
  {
    "path": "assets/Script/ECS/components/ComMovable.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"773fd91d-89d6-499e-9488-3d85f11938a1\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/components/ComNodeConfig.ts",
    "chars": 250,
    "preview": "import { ComType } from \"../lib/Const\";\nimport { ECSComponent } from \"../lib/ECSComponent\";\n\n@ECSComponent(ComType.ComNo"
  },
  {
    "path": "assets/Script/ECS/components/ComNodeConfig.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"ef2ff8f3-8ffa-49f6-8e55-b8ba0284a095\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/components/ComRoleConfig.ts",
    "chars": 357,
    "preview": "import { ComType } from \"../lib/Const\";\nimport { ECSComponent } from \"../lib/ECSComponent\";\n\n\n@ECSComponent(ComType.ComR"
  },
  {
    "path": "assets/Script/ECS/components/ComRoleConfig.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"a0036aea-32a4-4b9b-a587-5262ea4cedf7\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/components/ComTransform.ts",
    "chars": 278,
    "preview": "import { ComType } from \"../lib/Const\";\nimport { ECSComponent } from \"../lib/ECSComponent\";\n\n@ECSComponent(ComType.ComTr"
  },
  {
    "path": "assets/Script/ECS/components/ComTransform.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"0bb2991a-84c5-4b22-ade6-59d2e7e97252\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/components.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"3878b852-fe53-405d-a5bf-3978aedd9ce7\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/Script/ECS/lib/Const.ts",
    "chars": 295,
    "preview": "\nexport type EntityIndex = number;\n\nexport type ComPoolIndex = number;\n\nexport enum ComType {\n    ComCocosNode = 0,\n    "
  },
  {
    "path": "assets/Script/ECS/lib/Const.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"ce38ec2f-50f5-4f7a-ad24-48a576032322\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/lib/ECSComponent.ts",
    "chars": 1001,
    "preview": "import { ComType, EntityIndex } from \"./Const\";\r\n\r\n/** 构造函数 */\r\nexport interface ECSComConstructor extends Function {\r\n "
  },
  {
    "path": "assets/Script/ECS/lib/ECSComponent.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"58b062eb-ce1e-49dd-8520-15713b92a51f\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/lib/ECSComponentPool.ts",
    "chars": 1063,
    "preview": "import { ComPoolIndex } from \"./Const\";\nimport { ECSTypedComConstructor } from \"./ECSComponent\";\n\n/**\n * 组件池\n */\nexport "
  },
  {
    "path": "assets/Script/ECS/lib/ECSComponentPool.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"a40c60fb-7834-4de4-b1e9-6a346dd68e60\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/lib/ECSFilter.ts",
    "chars": 2012,
    "preview": "import { ComType, EntityIndex } from \"./Const\";\nimport { ECSWorld } from \"./ECSWorld\";\n\nexport class ECSFilter {\n    pri"
  },
  {
    "path": "assets/Script/ECS/lib/ECSFilter.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"9d20cc25-61b9-4be8-9e89-47bdcac35a5b\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/lib/ECSSystem.ts",
    "chars": 463,
    "preview": "import { ECSWorld } from \"./ECSWorld\";\n\nexport abstract class ECSSystem {\n    /** 连接 */\n    public abstract onAdd(world:"
  },
  {
    "path": "assets/Script/ECS/lib/ECSSystem.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"925b6e67-1234-4933-a867-339843b9a663\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/lib/ECSWorld.ts",
    "chars": 7981,
    "preview": "import { ECSFilter } from \"./ECSFilter\"\r\nimport { ECSComConstructor, GetComConstructor as GetComConstructor, GetComConst"
  },
  {
    "path": "assets/Script/ECS/lib/ECSWorld.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"decf2eee-3ef7-456d-bd8c-8d4eaa63e617\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/lib.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"fa6ac7d5-2bad-42ee-90ba-44147985428d\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/Script/ECS/systems/SysAttack.ts",
    "chars": 5749,
    "preview": "import { ComAttackable } from \"../components/ComAttackable\";\nimport { ComBeAttacked } from \"../components/ComBeAttacked\""
  },
  {
    "path": "assets/Script/ECS/systems/SysAttack.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"780c245c-45f2-47ae-a01a-b61dcfb3ab3e\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/systems/SysBehaviorTree.ts",
    "chars": 1848,
    "preview": "import { BT } from \"../../Common/BehaviorTree\";\nimport { ComBehaviorTree } from \"../components/ComBehaviorTree\";\nimport "
  },
  {
    "path": "assets/Script/ECS/systems/SysBehaviorTree.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"1b6bd6b5-cb8e-46e8-8052-8ed53e75a2e5\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/systems/SysCocosView.ts",
    "chars": 3895,
    "preview": "import CocosHelper from \"../../Common/CocosHelper\";\nimport { ComNodeConfig } from \"../components/ComNodeConfig\";\nimport "
  },
  {
    "path": "assets/Script/ECS/systems/SysCocosView.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"e4f95950-b571-48dd-8c95-7808eef0c336\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/systems/SysMonitor.ts",
    "chars": 3359,
    "preview": "import { ComMonitor } from \"../components/ComMonitor\";\nimport { ComRoleConfig } from \"../components/ComRoleConfig\";\nimpo"
  },
  {
    "path": "assets/Script/ECS/systems/SysMonitor.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"0b207deb-ff30-4fbe-aca7-2f77f299569d\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/systems/SysMovable.ts",
    "chars": 2491,
    "preview": "import { ComCocosNode as ComCocosNode } from \"../components/ComCocosNode\";\nimport { ComMovable } from \"../components/Com"
  },
  {
    "path": "assets/Script/ECS/systems/SysMovable.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"6f024564-9b8c-47ad-95eb-eca4afd96720\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/systems/SysRoleState.ts",
    "chars": 3496,
    "preview": "import { EventDeath, EventGraphicsDraw, EventHPChange, EventHurt, EventRun, EventStand } from \"../../Struct/NodeEvent\";\n"
  },
  {
    "path": "assets/Script/ECS/systems/SysRoleState.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"b679be6f-54ac-4790-99ff-41e3993bf130\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/systems.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"db93b255-0e1f-4c8a-adc8-d3d2fca077cc\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/Script/ECS/worlds/WorldCocosView.ts",
    "chars": 98,
    "preview": "import { ECSWorld } from \"../lib/ECSWorld\";\n\nexport class WorldCocosView extends ECSWorld {\n    \n}"
  },
  {
    "path": "assets/Script/ECS/worlds/WorldCocosView.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"2bbeb931-7f40-48e4-937d-13006b7f016b\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/ECS/worlds.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"00fbfe49-b0ae-426b-ae03-f11fba4ce919\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/Script/ECS.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"bf25ebfe-4ae5-4c18-8033-bb2bc7293a03\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/Script/Main.ts",
    "chars": 3832,
    "preview": "import { ECSController } from \"./Core/ECSController\";\nimport { ECSWorld } from \"./ECS/lib/ECSWorld\";\nimport { SysAttack "
  },
  {
    "path": "assets/Script/Main.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"e1b90feb-a217-4493-849d-9a611900d683\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/Struct/Direction.ts",
    "chars": 63,
    "preview": "export enum Direction {\n    Up,\n    Down,\n    Left,\n    Right\n}"
  },
  {
    "path": "assets/Script/Struct/Direction.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"436daff0-c505-45e0-b0ea-d804b6ef7fac\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/Struct/NodeEvent.ts",
    "chars": 1406,
    "preview": "export enum EventType {\n    Stand,          \n    Run,\n    Attack,\n    Hurt,\n    HPChange,\n    Death,\n    GraphicsDraw,\n}"
  },
  {
    "path": "assets/Script/Struct/NodeEvent.ts.meta",
    "chars": 225,
    "preview": "{\n  \"ver\": \"1.1.0\",\n  \"uuid\": \"8bdaf2f1-e01a-449c-88ab-e35aa4741b9c\",\n  \"importer\": \"typescript\",\n  \"isPlugin\": false,\n "
  },
  {
    "path": "assets/Script/Struct.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"e2f8f29f-d6d0-4172-802f-80e64a869ccf\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/Script.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"4734c20c-0db8-4eb2-92ea-e692f4d70934\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/Texture/HelloWorld.png.meta",
    "chars": 873,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"6aa0aa6a-ebee-4155-a088-a687a6aadec4\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/Texture/singleColor.png.meta",
    "chars": 862,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"a8027877-d8d6-4645-97a0-52d4a0123dba\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/Texture.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"7b81d4e8-ec84-4716-968d-500ac1d78a54\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/resources/3de2d4d5-8b98-4175-b44e-2516a9dae308113719czjoklju1eg0ued0.jpeg.meta",
    "chars": 924,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"3e42396d-4216-47bc-85bb-2b53217ef9db\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/Biker.prefab",
    "chars": 8978,
    "preview": "[\n  {\n    \"__type__\": \"cc.Prefab\",\n    \"_name\": \"\",\n    \"_objFlags\": 0,\n    \"_native\": \"\",\n    \"data\": {\n      \"__id__\":"
  },
  {
    "path": "assets/resources/Biker/Biker.prefab.meta",
    "chars": 193,
    "preview": "{\n  \"ver\": \"1.3.2\",\n  \"uuid\": \"e3f2d00f-b307-4c62-93ae-b968945b1b9f\",\n  \"importer\": \"prefab\",\n  \"optimizationPolicy\": \"A"
  },
  {
    "path": "assets/resources/Biker/anims/attack.anim",
    "chars": 1424,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"attack\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 1.01666666666"
  },
  {
    "path": "assets/resources/Biker/anims/attack.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"6ee5314b-888f-409e-902e-26749cad0015\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Biker/anims/death.anim",
    "chars": 1258,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"death\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 0.85,\n  \"sampl"
  },
  {
    "path": "assets/resources/Biker/anims/death.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"41ff0c6a-d2e8-4c9b-b789-bc4d370f7306\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Biker/anims/hurt.anim",
    "chars": 784,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"hurt\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 0.1833333333333"
  },
  {
    "path": "assets/resources/Biker/anims/hurt.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"28fe88ff-4bc8-4075-8e33-036bc8590ed4\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Biker/anims/punch.anim",
    "chars": 1423,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"punch\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 1.016666666666"
  },
  {
    "path": "assets/resources/Biker/anims/punch.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"61a5270f-7761-498d-bbec-b994abd2c8a5\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Biker/anims/run.anim",
    "chars": 1421,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"run\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 1.01666666666666"
  },
  {
    "path": "assets/resources/Biker/anims/run.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"1cac62f0-3a28-49cd-928f-3411415323b9\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Biker/anims/run_attack.anim",
    "chars": 1428,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"run_attack\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 1.0166666"
  },
  {
    "path": "assets/resources/Biker/anims/run_attack.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"62e0fbf7-19ce-44b3-a6b6-d24a24f0bdbd\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Biker/anims/stand.anim",
    "chars": 1104,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"stand\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 0.683333333333"
  },
  {
    "path": "assets/resources/Biker/anims/stand.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"da671d3b-78c7-475c-9896-f0fe061c1840\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Biker/anims.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"6dabbe66-aa6b-4573-9fa1-3da50292f5a1\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_attack1_01.png.meta",
    "chars": 870,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"397ddf1a-3b92-45a3-9987-1489244a0b70\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_attack1_02.png.meta",
    "chars": 870,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"8c655051-ccbe-4b02-9618-ccfff782d182\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_attack1_03.png.meta",
    "chars": 870,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"9c01c045-f333-4a61-a4dd-7433646e29a8\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_attack1_04.png.meta",
    "chars": 870,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"0441adca-6c6e-43bd-80d2-3ebfb9d20a50\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_attack1_05.png.meta",
    "chars": 870,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"8e2c4a5c-1324-4f94-a246-c3e79b4e449e\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_attack1_06.png.meta",
    "chars": 870,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"26e70da9-717b-4cbe-b170-9055ceb84725\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_death_01.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"4e628f90-5b36-4489-900a-f9efad09ab6e\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_death_02.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"27b8fb2c-f838-4223-9228-f8926a2dc94f\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_death_03.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"18f9eea3-126d-47dd-8016-5912dc68afc8\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_death_04.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"cb675cba-6b2e-476a-b5cb-391518496744\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_death_05.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"17ee8826-749d-43f4-a5b7-aabd55c7e665\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_death_06.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"1a4541bf-5ec6-4467-a67d-1dafd06c4bda\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_doublejump_01.png.meta",
    "chars": 873,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"cd40106f-66b2-41a9-b872-3abee81467eb\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_doublejump_02.png.meta",
    "chars": 873,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"feaccba2-89b0-4c74-97ef-1c1f1ac114ef\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_doublejump_03.png.meta",
    "chars": 873,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"35349264-63d2-441a-b839-2440c2f35178\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_doublejump_04.png.meta",
    "chars": 873,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"85147218-9966-489c-b990-e33521b038f4\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_doublejump_05.png.meta",
    "chars": 873,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"53ffd771-7016-4d77-8cbf-07cc9b29155a\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_doublejump_06.png.meta",
    "chars": 873,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"c7452e96-5985-43f7-83d3-a84c848d4fbc\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_hurt_01.png.meta",
    "chars": 867,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"5ce310ba-08af-4efe-ace3-b18176d03bd4\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_hurt_02.png.meta",
    "chars": 867,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"044c4a7b-0a13-4587-a5c0-294b12638e6d\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_idle_01.png.meta",
    "chars": 867,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"cd514cc5-2875-4212-bf51-ab4a39cdc944\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_idle_02.png.meta",
    "chars": 867,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"6f21de4e-4a5e-41b2-abdb-aba984844d7b\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_idle_03.png.meta",
    "chars": 867,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"f51789bc-de32-4d69-90cc-43e9bad0dc5f\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_idle_04.png.meta",
    "chars": 867,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"d8c6fe8d-be25-46b4-b136-0a4789cb02d2\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_jump_01.png.meta",
    "chars": 867,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"bee4ea4c-091f-43bf-b7af-3db398ef6f00\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_jump_02.png.meta",
    "chars": 867,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"365066c7-4d19-4f0e-a204-a1c3adb28643\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_jump_03.png.meta",
    "chars": 867,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"d5ed07ec-d82d-4dd8-a622-f3643150d2e2\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_jump_04.png.meta",
    "chars": 867,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"c8fc53e5-7721-451e-9f29-f9070502dd2d\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_punch_01.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"ef99adab-41b5-44a8-b656-1bd99d550994\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_punch_02.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"7d668faf-5fe2-4517-8fe4-dcd5f3e01da9\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_punch_03.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"a255cc1f-09dd-48aa-b9c0-d6067b236e0a\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_punch_04.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"94689b68-7c7b-40eb-8b48-3ff9a2c87bb4\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_punch_05.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"f9fac2d8-875c-4044-b69d-8dd57874dc6c\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_punch_06.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"131ddcee-0ed4-4aa2-8e4c-4a2f3bf4b3e5\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_run_01.png.meta",
    "chars": 866,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"e4889bab-b8df-4a16-be3c-aebf97c48df1\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_run_02.png.meta",
    "chars": 866,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"8d3719e4-ef66-427f-8b69-6fbe57a7d28d\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_run_03.png.meta",
    "chars": 866,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"58c749c2-b292-4366-bf9e-54c31bdd158c\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_run_04.png.meta",
    "chars": 866,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"9c728124-1958-487c-b6c1-5dc95a1659b6\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_run_05.png.meta",
    "chars": 866,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"ec97df45-d3e1-4cb8-99b9-762f934647d8\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_run_06.png.meta",
    "chars": 866,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"80aae1c1-1d5d-4525-a9dc-a743798d71c5\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_run_attack_01.png.meta",
    "chars": 873,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"a2454037-1d61-4a2a-b37f-62398a62d2c1\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_run_attack_02.png.meta",
    "chars": 873,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"882f9718-4482-40b2-9320-68573907fd48\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_run_attack_03.png.meta",
    "chars": 873,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"fe67f026-5e9b-46ac-b11d-5814b83c0477\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_run_attack_04.png.meta",
    "chars": 873,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"92f4a463-fcfa-45b6-916e-df97b5c41d78\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_run_attack_05.png.meta",
    "chars": 873,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"8e55ee8e-91ac-485a-8c61-11c393adfe94\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures/Biker_run_attack_06.png.meta",
    "chars": 873,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"78d30d4f-9ad8-45dd-ad05-82c5a57eab11\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Biker/textures.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"79383996-a72b-4d02-a8d3-8aa9ae6bd6e6\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/resources/Biker.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"a2761368-1fe6-41a6-a672-089f0f06e26f\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/resources/Cyborg/Cyborg.prefab",
    "chars": 8979,
    "preview": "[\n  {\n    \"__type__\": \"cc.Prefab\",\n    \"_name\": \"\",\n    \"_objFlags\": 0,\n    \"_native\": \"\",\n    \"data\": {\n      \"__id__\":"
  },
  {
    "path": "assets/resources/Cyborg/Cyborg.prefab.meta",
    "chars": 193,
    "preview": "{\n  \"ver\": \"1.3.2\",\n  \"uuid\": \"29335e7f-95e2-49fb-ac46-e57d5abccae7\",\n  \"importer\": \"prefab\",\n  \"optimizationPolicy\": \"A"
  },
  {
    "path": "assets/resources/Cyborg/anims/attack.anim",
    "chars": 1424,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"attack\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 1.01666666666"
  },
  {
    "path": "assets/resources/Cyborg/anims/attack.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"14ebb74b-5443-49d3-9219-dbce1dc486f3\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Cyborg/anims/death.anim",
    "chars": 1258,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"death\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 0.85,\n  \"sampl"
  },
  {
    "path": "assets/resources/Cyborg/anims/death.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"06b29a8c-4935-433d-88c1-55ac1c356e3c\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Cyborg/anims/hurt.anim",
    "chars": 784,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"hurt\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 0.1833333333333"
  },
  {
    "path": "assets/resources/Cyborg/anims/hurt.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"d7195236-fe3f-4bbc-8a23-97620a5e4b28\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Cyborg/anims/punch.anim",
    "chars": 1423,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"punch\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 1.016666666666"
  },
  {
    "path": "assets/resources/Cyborg/anims/punch.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"19f73a96-5ad0-4370-b349-4b98275e30b0\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Cyborg/anims/run.anim",
    "chars": 1421,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"run\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 1.01666666666666"
  },
  {
    "path": "assets/resources/Cyborg/anims/run.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"84a65f07-3523-4a44-9f7a-5adcb769a1d2\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Cyborg/anims/run_attack.anim",
    "chars": 1428,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"run_attack\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 1.0166666"
  },
  {
    "path": "assets/resources/Cyborg/anims/run_attack.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"5bb07b3b-d1a8-409a-a36a-76f1db51cc90\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Cyborg/anims/stand.anim",
    "chars": 1104,
    "preview": "{\n  \"__type__\": \"cc.AnimationClip\",\n  \"_name\": \"stand\",\n  \"_objFlags\": 0,\n  \"_native\": \"\",\n  \"_duration\": 0.683333333333"
  },
  {
    "path": "assets/resources/Cyborg/anims/stand.anim.meta",
    "chars": 120,
    "preview": "{\n  \"ver\": \"2.1.2\",\n  \"uuid\": \"6935664c-7199-4504-9a59-4a6404e15bfc\",\n  \"importer\": \"animation-clip\",\n  \"subMetas\": {}\n}"
  },
  {
    "path": "assets/resources/Cyborg/anims.meta",
    "chars": 274,
    "preview": "{\n  \"ver\": \"1.1.3\",\n  \"uuid\": \"7091e9e9-edc0-403e-9e77-2f9f98c5b5f9\",\n  \"importer\": \"folder\",\n  \"isBundle\": false,\n  \"bu"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_attack1_01.png.meta",
    "chars": 871,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"0bd3f602-4491-483a-b5b9-8405e3bcb230\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_attack1_02.png.meta",
    "chars": 871,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"dd63e118-d5d4-4a65-9cd7-2f7233efafa7\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_attack1_03.png.meta",
    "chars": 871,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"4e37a7c5-0490-48df-8c63-0be5b8058078\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_attack1_04.png.meta",
    "chars": 871,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"5e985aed-99c1-4069-9b0a-707b4dcf7714\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_attack1_05.png.meta",
    "chars": 871,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"01459ca7-3187-4a5b-a5e3-7cda494f02fc\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_attack1_06.png.meta",
    "chars": 871,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"2923e4d9-d09f-41a1-98b5-c9ac59064dc0\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_death_01.png.meta",
    "chars": 869,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"6c9568da-e8b7-4161-81b0-c2549994c61b\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_death_02.png.meta",
    "chars": 869,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"edd4476c-bd51-458f-89fd-a8dac6cca4d7\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_death_03.png.meta",
    "chars": 869,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"8e697472-e2a7-46d4-b8f9-0ab8b26e6dcf\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_death_04.png.meta",
    "chars": 869,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"b6a5c88f-95d9-4039-944a-74cc48d66128\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_death_05.png.meta",
    "chars": 869,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"3afa5599-5a11-483a-9540-00be1e63b90b\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_death_06.png.meta",
    "chars": 869,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"1a96cd7a-1fbb-4924-8aa9-a00e6d37d0db\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_doublejump_01.png.meta",
    "chars": 874,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"361f126f-2f89-403b-9d85-05d7774420da\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_doublejump_02.png.meta",
    "chars": 874,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"b7594df1-6838-42e1-905f-252fbb32254b\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_doublejump_03.png.meta",
    "chars": 874,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"6e4190bd-2a1f-4070-9191-15289fcbb324\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_doublejump_04.png.meta",
    "chars": 874,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"ee381a5a-d62f-4726-bc22-8791e8329640\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_doublejump_05.png.meta",
    "chars": 874,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"526f7962-abae-48a8-8786-097df411c6c8\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_doublejump_06.png.meta",
    "chars": 874,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"69019363-8568-4cdb-9520-fb2c7b131f45\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_hurt_01.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"b3ed8b92-9d79-4199-b9e6-9b94c357d4b4\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_hurt_02.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"6f70d3df-1cfb-426c-96df-80f4fb7a9732\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_idle_01.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"3f7cfdf0-6a86-40a5-8b3e-740b85000ada\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_idle_02.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"38fa3fa9-5f9e-46d3-9cac-4f3bb802fc6b\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_idle_03.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"2f5dc4a3-6426-4863-aa9c-e9a16e7fe721\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_idle_04.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"31fe6446-8928-49e9-96d1-7b5b73506103\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_jump_01.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"5f7895ab-f5d9-4281-8308-1993a0398539\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_jump_02.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"a8e3a356-cd66-40a4-b24e-da6fa28ab993\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_jump_03.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"26e90e4f-2fbe-46ff-a564-b26cf849beb5\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_jump_04.png.meta",
    "chars": 868,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"484f65ed-6b62-4a39-acec-cfee3225a678\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_punch_01.png.meta",
    "chars": 869,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"658eda79-e8d3-42e1-952c-0a21517b9735\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_punch_02.png.meta",
    "chars": 869,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"52318473-a0b2-4c74-bb9b-432ab30f719e\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_punch_03.png.meta",
    "chars": 869,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"cd63eb96-2cce-4839-b55c-b9ce3f787ba3\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_punch_04.png.meta",
    "chars": 869,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"7d4129dc-acf6-4fc5-a68a-789481b6768a\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_punch_05.png.meta",
    "chars": 869,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"094888fd-1759-4560-97e4-cc590e4ce6d9\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_punch_06.png.meta",
    "chars": 869,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"045ec459-0065-46fd-a0ab-f4edbd4a2891\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  },
  {
    "path": "assets/resources/Cyborg/textures/Cyborg_run_01.png.meta",
    "chars": 867,
    "preview": "{\n  \"ver\": \"2.3.7\",\n  \"uuid\": \"13b5d9d4-f1dd-455d-bb0d-2208ac0e1e80\",\n  \"importer\": \"texture\",\n  \"type\": \"sprite\",\n  \"wr"
  }
]

// ... and 27 more files (download for full content)

About this extraction

This page contains the full source code of the kirikayakazuto/CocosCreator_ECS GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 227 files (1.3 MB), approximately 424.5k tokens, and a symbol index with 796 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!