From 279218b4c3998694ce068e0a18640506222cb2cc Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 8 Nov 2022 19:45:57 +0100 Subject: [PATCH] new structure, spawner, rebind --- assets/Media/Prefabs/Enemy.prefab | 5 +- assets/Scenes/scene.scene | 818 +++++++++++++----- assets/Scripts/CollisionSystem.ts | 22 - assets/Scripts/Enemy.ts | 19 - assets/Scripts/Game.meta | 12 + assets/Scripts/Game/Collision.meta | 12 + .../Game/Collision/PlayerCollisionSystem.ts | 63 ++ .../Collision/PlayerCollisionSystem.ts.meta} | 0 .../Game/Collision/WeaponCollisionSystem.ts | 15 + .../Collision/WeaponCollisionSystem.ts.meta | 9 + assets/Scripts/Game/Enemy.meta | 12 + assets/Scripts/Game/Enemy/Enemy.ts | 45 + assets/Scripts/{ => Game/Enemy}/Enemy.ts.meta | 0 assets/Scripts/Game/Enemy/EnemySpawner.ts | 41 + .../Scripts/Game/Enemy/EnemySpawner.ts.meta | 9 + assets/Scripts/Game/GameBootstrapper.ts | 34 + .../{ => Game}/GameBootstrapper.ts.meta | 0 assets/Scripts/Game/GroupType.ts | 8 + assets/Scripts/Game/GroupType.ts.meta | 9 + assets/Scripts/Game/Input.meta | 12 + .../{ => Game/Input}/VirtualJoystic.ts | 0 .../{ => Game/Input}/VirtualJoystic.ts.meta | 0 assets/Scripts/Game/Player.meta | 12 + assets/Scripts/{ => Game/Player}/Player.ts | 17 +- .../Scripts/{ => Game/Player}/Player.ts.meta | 0 assets/Scripts/Game/Player/PlayerUI.meta | 12 + .../Game/Player/PlayerUI/PlayerHealthUI.ts | 19 + .../Player/PlayerUI/PlayerHealthUI.ts.meta | 9 + .../Scripts/Game/Player/PlayerUI/PlayerUI.ts | 13 + .../Game/Player/PlayerUI/PlayerUI.ts.meta | 9 + assets/Scripts/Game/Player/UnitHealth.ts | 42 + assets/Scripts/Game/Player/UnitHealth.ts.meta | 9 + assets/Scripts/{ => Game}/Weapon.ts | 15 +- assets/Scripts/{ => Game}/Weapon.ts.meta | 0 assets/Scripts/GameBootstrapper.ts | 51 -- assets/Scripts/Services.meta | 2 +- .../Scripts/Services/EventSystem/ISignal.ts | 2 +- assets/Scripts/Services/EventSystem/Signal.ts | 12 +- assets/Scripts/Services/GameTimer.ts | 21 + assets/Scripts/Services/GameTimer.ts.meta | 9 + assets/Scripts/Services/UI.meta | 12 + assets/Scripts/Services/Utils.meta | 12 + assets/Scripts/Services/Utils/AsyncUtils.ts | 3 + .../Scripts/Services/Utils/AsyncUtils.ts.meta | 9 + settings/v2/packages/project.json | 24 + 45 files changed, 1157 insertions(+), 302 deletions(-) delete mode 100644 assets/Scripts/CollisionSystem.ts delete mode 100644 assets/Scripts/Enemy.ts create mode 100644 assets/Scripts/Game.meta create mode 100644 assets/Scripts/Game/Collision.meta create mode 100644 assets/Scripts/Game/Collision/PlayerCollisionSystem.ts rename assets/Scripts/{CollisionSystem.ts.meta => Game/Collision/PlayerCollisionSystem.ts.meta} (100%) create mode 100644 assets/Scripts/Game/Collision/WeaponCollisionSystem.ts create mode 100644 assets/Scripts/Game/Collision/WeaponCollisionSystem.ts.meta create mode 100644 assets/Scripts/Game/Enemy.meta create mode 100644 assets/Scripts/Game/Enemy/Enemy.ts rename assets/Scripts/{ => Game/Enemy}/Enemy.ts.meta (100%) create mode 100644 assets/Scripts/Game/Enemy/EnemySpawner.ts create mode 100644 assets/Scripts/Game/Enemy/EnemySpawner.ts.meta create mode 100644 assets/Scripts/Game/GameBootstrapper.ts rename assets/Scripts/{ => Game}/GameBootstrapper.ts.meta (100%) create mode 100644 assets/Scripts/Game/GroupType.ts create mode 100644 assets/Scripts/Game/GroupType.ts.meta create mode 100644 assets/Scripts/Game/Input.meta rename assets/Scripts/{ => Game/Input}/VirtualJoystic.ts (100%) rename assets/Scripts/{ => Game/Input}/VirtualJoystic.ts.meta (100%) create mode 100644 assets/Scripts/Game/Player.meta rename assets/Scripts/{ => Game/Player}/Player.ts (67%) rename assets/Scripts/{ => Game/Player}/Player.ts.meta (100%) create mode 100644 assets/Scripts/Game/Player/PlayerUI.meta create mode 100644 assets/Scripts/Game/Player/PlayerUI/PlayerHealthUI.ts create mode 100644 assets/Scripts/Game/Player/PlayerUI/PlayerHealthUI.ts.meta create mode 100644 assets/Scripts/Game/Player/PlayerUI/PlayerUI.ts create mode 100644 assets/Scripts/Game/Player/PlayerUI/PlayerUI.ts.meta create mode 100644 assets/Scripts/Game/Player/UnitHealth.ts create mode 100644 assets/Scripts/Game/Player/UnitHealth.ts.meta rename assets/Scripts/{ => Game}/Weapon.ts (75%) rename assets/Scripts/{ => Game}/Weapon.ts.meta (100%) delete mode 100644 assets/Scripts/GameBootstrapper.ts create mode 100644 assets/Scripts/Services/GameTimer.ts create mode 100644 assets/Scripts/Services/GameTimer.ts.meta create mode 100644 assets/Scripts/Services/UI.meta create mode 100644 assets/Scripts/Services/Utils.meta create mode 100644 assets/Scripts/Services/Utils/AsyncUtils.ts create mode 100644 assets/Scripts/Services/Utils/AsyncUtils.ts.meta create mode 100644 settings/v2/packages/project.json diff --git a/assets/Media/Prefabs/Enemy.prefab b/assets/Media/Prefabs/Enemy.prefab index 3994818..fe5eb3f 100644 --- a/assets/Media/Prefabs/Enemy.prefab +++ b/assets/Media/Prefabs/Enemy.prefab @@ -147,7 +147,7 @@ "__id__": 7 }, "tag": 0, - "_group": 1, + "_group": 4, "_density": 1, "_sensor": false, "_friction": 0.2, @@ -179,6 +179,9 @@ "__prefab": { "__id__": 9 }, + "collider": { + "__id__": 6 + }, "_id": "" }, { diff --git a/assets/Scenes/scene.scene b/assets/Scenes/scene.scene index 893b87b..779ee92 100644 --- a/assets/Scenes/scene.scene +++ b/assets/Scenes/scene.scene @@ -21,11 +21,11 @@ "_active": true, "_components": [], "_prefab": { - "__id__": 44 + "__id__": 53 }, "autoReleaseAssets": false, "_globals": { - "__id__": 45 + "__id__": 54 }, "_id": "cffa5b19-2043-4cef-8221-1a10ab7a2c1f" }, @@ -44,35 +44,35 @@ "__id__": 5 }, { - "__id__": 13 + "__id__": 14 }, { - "__id__": 22 + "__id__": 34 }, { - "__id__": 27 + "__id__": 47 } ], "_active": true, "_components": [ { - "__id__": 40 + "__id__": 49 }, { - "__id__": 41 + "__id__": 50 }, { - "__id__": 42 + "__id__": 51 }, { - "__id__": 43 + "__id__": 52 } ], "_prefab": null, "_lpos": { "__type__": "cc.Vec3", - "x": 480, - "y": 320.00000000000006, + "x": 479.99999999999994, + "y": 319.99999999999994, "z": 0 }, "_lrot": { @@ -153,7 +153,7 @@ "_priority": 1073741824, "_fov": 45, "_fovAxis": 0, - "_orthoHeight": 320, + "_orthoHeight": 656.050156739812, "_near": 0, "_far": 2000, "_color": { @@ -183,114 +183,6 @@ "_trackingType": 0, "_id": "63WIch3o5BEYRlXzTT0oWc" }, - { - "__type__": "cc.Node", - "_objFlags": 0, - "_parent": { - "__id__": 2 - }, - "_prefab": { - "__id__": 6 - }, - "__editorExtras__": {} - }, - { - "__type__": "cc.PrefabInfo", - "root": { - "__id__": 5 - }, - "asset": { - "__uuid__": "fc9a455d-1b5f-460e-96eb-7c0ebf07d3d0", - "__expectedType__": "cc.Prefab" - }, - "fileId": "b3GFrfkl5AR4Q9jndybzln", - "instance": { - "__id__": 7 - } - }, - { - "__type__": "cc.PrefabInstance", - "fileId": "6eLx/bqYlD4q9xuucUXxZQ", - "mountedChildren": [], - "mountedComponents": [], - "propertyOverrides": [ - { - "__id__": 8 - }, - { - "__id__": 10 - }, - { - "__id__": 11 - }, - { - "__id__": 12 - } - ], - "removedComponents": [] - }, - { - "__type__": "CCPropertyOverrideInfo", - "targetInfo": { - "__id__": 9 - }, - "propertyPath": [ - "_name" - ], - "value": "Enemy" - }, - { - "__type__": "cc.TargetInfo", - "localID": [ - "b3GFrfkl5AR4Q9jndybzln" - ] - }, - { - "__type__": "CCPropertyOverrideInfo", - "targetInfo": { - "__id__": 9 - }, - "propertyPath": [ - "_lpos" - ], - "value": { - "__type__": "cc.Vec3", - "x": 0, - "y": 0, - "z": 0 - } - }, - { - "__type__": "CCPropertyOverrideInfo", - "targetInfo": { - "__id__": 9 - }, - "propertyPath": [ - "_lrot" - ], - "value": { - "__type__": "cc.Quat", - "x": 0, - "y": 0, - "z": 0, - "w": 1 - } - }, - { - "__type__": "CCPropertyOverrideInfo", - "targetInfo": { - "__id__": 9 - }, - "propertyPath": [ - "_euler" - ], - "value": { - "__type__": "cc.Vec3", - "x": 0, - "y": 0, - "z": 0 - } - }, { "__type__": "cc.Node", "_name": "Weapon", @@ -300,13 +192,13 @@ }, "_children": [ { - "__id__": 14 + "__id__": 6 } ], "_active": true, "_components": [ { - "__id__": 21 + "__id__": 13 } ], "_prefab": null, @@ -343,20 +235,20 @@ "_name": "AnimatedWeapon", "_objFlags": 0, "_parent": { - "__id__": 13 + "__id__": 5 }, "_children": [ { - "__id__": 15 + "__id__": 7 } ], "_active": true, "_components": [ { - "__id__": 19 + "__id__": 11 }, { - "__id__": 20 + "__id__": 12 } ], "_prefab": null, @@ -393,19 +285,19 @@ "_name": "WeaponCollider", "_objFlags": 0, "_parent": { - "__id__": 14 + "__id__": 6 }, "_children": [], "_active": true, "_components": [ { - "__id__": 16 + "__id__": 8 }, { - "__id__": 17 + "__id__": 9 }, { - "__id__": 18 + "__id__": 10 } ], "_prefab": null, @@ -442,7 +334,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 15 + "__id__": 7 }, "_enabled": true, "__prefab": null, @@ -463,7 +355,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 15 + "__id__": 7 }, "_enabled": true, "__prefab": null, @@ -501,12 +393,12 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 15 + "__id__": 7 }, "_enabled": true, "__prefab": null, "tag": 0, - "_group": 1, + "_group": 8, "_density": 1, "_sensor": false, "_friction": 0.2, @@ -528,7 +420,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 14 + "__id__": 6 }, "_enabled": true, "__prefab": null, @@ -549,7 +441,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 14 + "__id__": 6 }, "_enabled": true, "__prefab": null, @@ -571,15 +463,15 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 13 + "__id__": 5 }, "_enabled": true, "__prefab": null, "weaponAnimation": { - "__id__": 20 + "__id__": 12 }, "collider": { - "__id__": 18 + "__id__": 10 }, "_id": "femtdMmA5Ax5K78hjELCcD" }, @@ -590,20 +482,24 @@ "_parent": { "__id__": 2 }, - "_children": [], + "_children": [ + { + "__id__": 15 + } + ], "_active": true, "_components": [ { - "__id__": 23 + "__id__": 30 }, { - "__id__": 24 + "__id__": 31 }, { - "__id__": 25 + "__id__": 32 }, { - "__id__": 26 + "__id__": 33 } ], "_prefab": null, @@ -635,12 +531,484 @@ }, "_id": "fbcM/H31RNxK0HvQrwpElL" }, + { + "__type__": "cc.Node", + "_name": "PlayerUI", + "_objFlags": 0, + "_parent": { + "__id__": 14 + }, + "_children": [ + { + "__id__": 16 + } + ], + "_active": true, + "_components": [ + { + "__id__": 28 + }, + { + "__id__": 29 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "17O88PfANI6rsBSSI0OURh" + }, + { + "__type__": "cc.Node", + "_name": "PlayerHealthUI", + "_objFlags": 0, + "_parent": { + "__id__": 15 + }, + "_children": [ + { + "__id__": 17 + }, + { + "__id__": 20 + } + ], + "_active": true, + "_components": [ + { + "__id__": 26 + }, + { + "__id__": 27 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 40, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "c7Rq/RrTZLT6tjnefq9TsH" + }, + { + "__type__": "cc.Node", + "_name": "Background", + "_objFlags": 0, + "_parent": { + "__id__": 16 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 18 + }, + { + "__id__": 19 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "99v8mStXNIB48+PtVdOBM6" + }, { "__type__": "cc.UITransform", "_name": "", "_objFlags": 0, "node": { - "__id__": 22 + "__id__": 17 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 80, + "height": 16 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "af1pW4oehMG6u3P3UUtlU+" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 17 + }, + "_enabled": true, + "__prefab": null, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 36, + "g": 36, + "b": 247, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "f2tzNuW69CaKOvG2f5fHHk" + }, + { + "__type__": "cc.Node", + "_name": "HpBar", + "_objFlags": 0, + "_parent": { + "__id__": 16 + }, + "_children": [ + { + "__id__": 21 + } + ], + "_active": true, + "_components": [ + { + "__id__": 24 + }, + { + "__id__": 25 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "8bKR644TFCkZEmoGCLxwic" + }, + { + "__type__": "cc.Node", + "_name": "MovableBar", + "_objFlags": 0, + "_parent": { + "__id__": 20 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 22 + }, + { + "__id__": 23 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": -40, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "13SpGb/WNFMZDU0UFO16Tv" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 21 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 80, + "height": 16 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0.5 + }, + "_id": "0aprT4wkVCyoy0fVVlgq18" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 21 + }, + "_enabled": true, + "__prefab": null, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 0, + "b": 0, + "a": 255 + }, + "_spriteFrame": { + "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941", + "__expectedType__": "cc.SpriteFrame" + }, + "_type": 0, + "_fillType": 0, + "_sizeMode": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_useGrayscale": false, + "_atlas": null, + "_id": "15yySBxZ9Fh5n6bawRDCal" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 20 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 80, + "height": 16 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "4ewDB5nyZC6IysYcsZZGgI" + }, + { + "__type__": "cc.ProgressBar", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 20 + }, + "_enabled": true, + "__prefab": null, + "_barSprite": { + "__id__": 23 + }, + "_mode": 0, + "_totalLength": 80, + "_progress": 1, + "_reverse": false, + "_id": "f5fDLptZVG5r61Mbz1dwT+" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 16 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 80, + "height": 16 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "7ekl5hIYtHP4LyYKcIy1P+" + }, + { + "__type__": "84a1cBXLvhOrYkDV1Pzasc1", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 16 + }, + "_enabled": true, + "__prefab": null, + "healthBar": { + "__id__": 25 + }, + "_id": "fdR9eSdI9Kh7IrotzIY0Rb" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 15 + }, + "_enabled": true, + "__prefab": null, + "_contentSize": { + "__type__": "cc.Size", + "width": 100, + "height": 100 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_id": "57ch5XLAJEmKuYOYTW3ZCz" + }, + { + "__type__": "634f6dvwzVCooXo8hTpzl63", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 15 + }, + "_enabled": true, + "__prefab": null, + "healthUI": { + "__id__": 27 + }, + "_id": "d2D9WtiThPe6mF1BVz5+iU" + }, + { + "__type__": "cc.UITransform", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 14 }, "_enabled": true, "__prefab": null, @@ -661,7 +1029,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 22 + "__id__": 14 }, "_enabled": true, "__prefab": null, @@ -699,13 +1067,16 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 22 + "__id__": 14 }, "_enabled": true, "__prefab": null, "speed": 100, "collider": { - "__id__": 26 + "__id__": 33 + }, + "playerUI": { + "__id__": 29 }, "_id": "5aDEGDNWpIaL+U2iIxK4vA" }, @@ -714,12 +1085,12 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 22 + "__id__": 14 }, "_enabled": true, "__prefab": null, "tag": 0, - "_group": 1, + "_group": 2, "_density": 1, "_sensor": false, "_friction": 0.2, @@ -745,19 +1116,19 @@ }, "_children": [ { - "__id__": 28 + "__id__": 35 }, { - "__id__": 35 + "__id__": 42 } ], "_active": true, "_components": [ { - "__id__": 38 + "__id__": 45 }, { - "__id__": 39 + "__id__": 46 } ], "_prefab": null, @@ -794,23 +1165,23 @@ "_name": "VirtualJoystic", "_objFlags": 0, "_parent": { - "__id__": 27 + "__id__": 34 }, "_children": [ { - "__id__": 29 + "__id__": 36 } ], "_active": true, "_components": [ { - "__id__": 32 + "__id__": 39 }, { - "__id__": 33 + "__id__": 40 }, { - "__id__": 34 + "__id__": 41 } ], "_prefab": null, @@ -847,16 +1218,16 @@ "_name": "Knob", "_objFlags": 0, "_parent": { - "__id__": 28 + "__id__": 35 }, "_children": [], "_active": true, "_components": [ { - "__id__": 30 + "__id__": 37 }, { - "__id__": 31 + "__id__": 38 } ], "_prefab": null, @@ -893,7 +1264,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 29 + "__id__": 36 }, "_enabled": true, "__prefab": null, @@ -914,7 +1285,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 29 + "__id__": 36 }, "_enabled": true, "__prefab": null, @@ -952,7 +1323,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 28 + "__id__": 35 }, "_enabled": true, "__prefab": null, @@ -973,7 +1344,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 28 + "__id__": 35 }, "_enabled": true, "__prefab": null, @@ -1011,13 +1382,13 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 28 + "__id__": 35 }, "_enabled": true, "__prefab": null, "maxDistance": 50, "knob": { - "__id__": 29 + "__id__": 36 }, "_id": "50ceZG62tGlYXvZWEvSDKl" }, @@ -1026,16 +1397,16 @@ "_name": "BottomRight", "_objFlags": 0, "_parent": { - "__id__": 27 + "__id__": 34 }, "_children": [], "_active": true, "_components": [ { - "__id__": 36 + "__id__": 43 }, { - "__id__": 37 + "__id__": 44 } ], "_prefab": null, @@ -1072,7 +1443,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 35 + "__id__": 42 }, "_enabled": true, "__prefab": null, @@ -1093,7 +1464,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 35 + "__id__": 42 }, "_enabled": true, "__prefab": null, @@ -1122,7 +1493,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 27 + "__id__": 34 }, "_enabled": true, "__prefab": null, @@ -1143,7 +1514,7 @@ "_name": "", "_objFlags": 0, "node": { - "__id__": 27 + "__id__": 34 }, "_enabled": true, "__prefab": null, @@ -1167,6 +1538,66 @@ "_lockFlags": 0, "_id": "63krxYCjdP0quUNgpkCXUc" }, + { + "__type__": "cc.Node", + "_name": "EnemySpawner", + "_objFlags": 0, + "_parent": { + "__id__": 2 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 48 + } + ], + "_prefab": null, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_lrot": { + "__type__": "cc.Quat", + "x": 0, + "y": 0, + "z": 0, + "w": 1 + }, + "_lscale": { + "__type__": "cc.Vec3", + "x": 1, + "y": 1, + "z": 1 + }, + "_layer": 33554432, + "_euler": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_id": "936Vpv3ydL8JZMvakVgAP5" + }, + { + "__type__": "8aa2aOTzVFLtKl5CV5vzpWp", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 47 + }, + "_enabled": true, + "__prefab": null, + "enemies": [ + { + "__uuid__": "fc9a455d-1b5f-460e-96eb-7c0ebf07d3d0", + "__expectedType__": "cc.Prefab" + } + ], + "_id": "0bYOmE6uFKe6bZiYUsXVFn" + }, { "__type__": "cc.UITransform", "_name": "", @@ -1214,10 +1645,10 @@ "__prefab": null, "_alignFlags": 45, "_target": null, - "_left": 0, - "_right": 5.684341886080802e-14, - "_top": 5.684341886080802e-14, - "_bottom": 5.684341886080802e-14, + "_left": -5.684341886080802e-14, + "_right": 0, + "_top": -5.684341886080802e-14, + "_bottom": -5.684341886080802e-14, "_horizontalCenter": 0, "_verticalCenter": 0, "_isAbsLeft": true, @@ -1242,46 +1673,41 @@ "_enabled": true, "__prefab": null, "virtualJoystic": { - "__id__": 34 + "__id__": 41 }, "player": { - "__id__": 25 + "__id__": 32 }, "weapon": { - "__id__": 21 + "__id__": 13 }, - "enemy": { - "__uuid__": "fc9a455d-1b5f-460e-96eb-7c0ebf07d3d0", - "__expectedType__": "cc.Prefab" + "enemySpawner": { + "__id__": 48 }, "strikeDelay": 2, + "collisionDelay": 0.5, "_id": "81HHJkTWZDO60EyXTSS38c" }, { "__type__": "cc.PrefabInfo", - "fileId": "cffa5b19-2043-4cef-8221-1a10ab7a2c1f", - "nestedPrefabInstanceRoots": [ - { - "__id__": 5 - } - ] + "fileId": "cffa5b19-2043-4cef-8221-1a10ab7a2c1f" }, { "__type__": "cc.SceneGlobals", "ambient": { - "__id__": 46 + "__id__": 55 }, "shadows": { - "__id__": 47 + "__id__": 56 }, "_skybox": { - "__id__": 48 + "__id__": 57 }, "fog": { - "__id__": 49 + "__id__": 58 }, "octree": { - "__id__": 50 + "__id__": 59 } }, { diff --git a/assets/Scripts/CollisionSystem.ts b/assets/Scripts/CollisionSystem.ts deleted file mode 100644 index 4c0c73c..0000000 --- a/assets/Scripts/CollisionSystem.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Collider2D, Contact2DType } from "cc"; -import { Enemy, IDamageDealing } from "./Enemy"; -import { Player } from "./Player"; -import { Weapon } from "./Weapon"; - -export class CollisionSystem { - public constructor(player: Player, weapon: Weapon) { - player.Collider.on(Contact2DType.BEGIN_CONTACT, this.onPlayerContactBegin, this); - weapon.Collider.on(Contact2DType.BEGIN_CONTACT, this.onWeaponContactBegin, this); - } - - private onWeaponContactBegin(_selfCollider: Collider2D, otherCollider: Collider2D): void { - console.log("Weapon contact! " + otherCollider.node.name); - } - - private onPlayerContactBegin(_selfCollider: Collider2D, otherCollider: Collider2D): void { - console.log("Player contact! " + otherCollider.node.name); - const damageDealing: IDamageDealing = otherCollider.node.getComponent(Enemy); - - console.log("DAMAGE: " + damageDealing.Damage); - } -} diff --git a/assets/Scripts/Enemy.ts b/assets/Scripts/Enemy.ts deleted file mode 100644 index 45e6bfb..0000000 --- a/assets/Scripts/Enemy.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { BoxCollider2D, Component, _decorator } from "cc"; -const { ccclass, property } = _decorator; - -@ccclass("Enemy") -export class Enemy extends Component implements IDamageDealing { - @property(BoxCollider2D) public collider: BoxCollider2D; - - public get Collider(): BoxCollider2D { - return this.collider; - } - - public get Damage(): number { - return 3; - } -} - -export interface IDamageDealing { - Damage: number; -} diff --git a/assets/Scripts/Game.meta b/assets/Scripts/Game.meta new file mode 100644 index 0000000..e7962ad --- /dev/null +++ b/assets/Scripts/Game.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "e0f54aa0-97e2-4780-9d6e-c51245df0815", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/Scripts/Game/Collision.meta b/assets/Scripts/Game/Collision.meta new file mode 100644 index 0000000..f88d5ee --- /dev/null +++ b/assets/Scripts/Game/Collision.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "06e5187a-01d6-4e7c-a597-cf6b9be31705", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/Scripts/Game/Collision/PlayerCollisionSystem.ts b/assets/Scripts/Game/Collision/PlayerCollisionSystem.ts new file mode 100644 index 0000000..785b35f --- /dev/null +++ b/assets/Scripts/Game/Collision/PlayerCollisionSystem.ts @@ -0,0 +1,63 @@ +import { Collider2D, Contact2DType } from "cc"; +import { GroupType } from "../GroupType"; +import { Player } from "../Player/Player"; +import { GameTimer } from "../../Services/GameTimer"; +import { Enemy } from "../Enemy/Enemy"; + +export class PlayerCollisionSystem { + private playerContacts: Collider2D[] = []; + private collisionTimer: GameTimer; + private player: Player; + + private groupToResolver: Map void> = new Map void>(); + + public constructor(player: Player, collisionDelay: number) { + this.player = player; + + player.Collider.on(Contact2DType.BEGIN_CONTACT, this.onPlayerContactBegin, this); + player.Collider.on(Contact2DType.END_CONTACT, this.onPlayerContactEnd, this); + + this.collisionTimer = new GameTimer(collisionDelay); + + this.groupToResolver.set(GroupType.ENEMY, this.resolveEnemyContact.bind(this)); + } + + public gameTick(deltaTime: number): void { + this.collisionTimer.gameTick(deltaTime); + if (this.collisionTimer.tryFinishPeriod()) { + this.resolveAllContacts(); + } + } + + private onPlayerContactBegin(_selfCollider: Collider2D, otherCollider: Collider2D): void { + this.playerContacts.push(otherCollider); + this.resolveContact(otherCollider); + } + + private onPlayerContactEnd(_selfCollider: Collider2D, otherCollider: Collider2D): void { + const index: number = this.playerContacts.indexOf(otherCollider); + if (index != -1) { + this.playerContacts.splice(index, 1); + } + } + + private resolveAllContacts(): void { + for (let i = 0; i < this.playerContacts.length; i++) { + this.resolveContact(this.playerContacts[i]); + } + } + + private resolveContact(otherCollider: Collider2D): void { + if (this.groupToResolver.has(otherCollider.group)) { + this.groupToResolver.get(otherCollider.group)(otherCollider); + } else { + console.log("Collided with undefined group: " + otherCollider.group); + } + } + + private resolveEnemyContact(enemyCollider: Collider2D): void { + const damage: number = enemyCollider.node.getComponent(Enemy).Damage; + console.log("Collided with enemy: Damage: " + damage); + this.player.Health.damage(damage); + } +} diff --git a/assets/Scripts/CollisionSystem.ts.meta b/assets/Scripts/Game/Collision/PlayerCollisionSystem.ts.meta similarity index 100% rename from assets/Scripts/CollisionSystem.ts.meta rename to assets/Scripts/Game/Collision/PlayerCollisionSystem.ts.meta diff --git a/assets/Scripts/Game/Collision/WeaponCollisionSystem.ts b/assets/Scripts/Game/Collision/WeaponCollisionSystem.ts new file mode 100644 index 0000000..a35b74e --- /dev/null +++ b/assets/Scripts/Game/Collision/WeaponCollisionSystem.ts @@ -0,0 +1,15 @@ +import { Collider2D, Contact2DType } from "cc"; +import { Enemy } from "../Enemy/Enemy"; +import { Weapon } from "../Weapon"; + +export class WeaponCollisionSystem { + private weapon: Weapon; + public constructor(weapon: Weapon) { + this.weapon = weapon; + weapon.Collider.on(Contact2DType.BEGIN_CONTACT, this.onWeaponContactBegin, this); + } + + private onWeaponContactBegin(_selfCollider: Collider2D, otherCollider: Collider2D): void { + otherCollider.getComponent(Enemy).dealDamage(this.weapon.Damage); + } +} diff --git a/assets/Scripts/Game/Collision/WeaponCollisionSystem.ts.meta b/assets/Scripts/Game/Collision/WeaponCollisionSystem.ts.meta new file mode 100644 index 0000000..4d01bb7 --- /dev/null +++ b/assets/Scripts/Game/Collision/WeaponCollisionSystem.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "eea89f2a-424b-4169-b2b7-7bf5261e9750", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/Enemy.meta b/assets/Scripts/Game/Enemy.meta new file mode 100644 index 0000000..27d2b1a --- /dev/null +++ b/assets/Scripts/Game/Enemy.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "e71832fc-dfd7-409d-924d-f87037c811e4", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/Scripts/Game/Enemy/Enemy.ts b/assets/Scripts/Game/Enemy/Enemy.ts new file mode 100644 index 0000000..1cab894 --- /dev/null +++ b/assets/Scripts/Game/Enemy/Enemy.ts @@ -0,0 +1,45 @@ +import { BoxCollider2D, Component, _decorator } from "cc"; +import { ISignal } from "../../Services/EventSystem/ISignal"; +import { Signal } from "../../Services/EventSystem/Signal"; +import { UnitHealth } from "../Player/UnitHealth"; +const { ccclass, property } = _decorator; + +@ccclass("Enemy") +export class Enemy extends Component implements IDamageDealing { + @property(BoxCollider2D) public collider: BoxCollider2D; + + private health: UnitHealth = new UnitHealth(1); + private deathEvent: Signal = new Signal(); + + public setup(): void { + this.node.active = true; + this.health = new UnitHealth(1); + } + + public get Collider(): BoxCollider2D { + return this.collider; + } + + public get Damage(): number { + return 3; + } + + public get Health(): UnitHealth { + return this.health; + } + + public get DeathEvent(): ISignal { + return this.deathEvent; + } + + public dealDamage(points: number): void { + this.health.damage(points); + if (!this.health.IsAlive) { + this.deathEvent.trigger(this); + } + } +} + +export interface IDamageDealing { + Damage: number; +} diff --git a/assets/Scripts/Enemy.ts.meta b/assets/Scripts/Game/Enemy/Enemy.ts.meta similarity index 100% rename from assets/Scripts/Enemy.ts.meta rename to assets/Scripts/Game/Enemy/Enemy.ts.meta diff --git a/assets/Scripts/Game/Enemy/EnemySpawner.ts b/assets/Scripts/Game/Enemy/EnemySpawner.ts new file mode 100644 index 0000000..369aab5 --- /dev/null +++ b/assets/Scripts/Game/Enemy/EnemySpawner.ts @@ -0,0 +1,41 @@ +import { Component, Prefab, randomRange, Vec3, _decorator } from "cc"; +import { GameTimer } from "../../Services/GameTimer"; +import { ObjectPool } from "../../Services/ObjectPool"; +import { Enemy } from "./Enemy"; +const { ccclass, property } = _decorator; + +@ccclass("EnemySpawner") +export class EnemySpawner extends Component { + @property(Prefab) private enemies: Prefab[] = []; + + private enemyPool: ObjectPool; + private spawnTimer: GameTimer; + + public init(): void { + this.enemyPool = new ObjectPool(this.enemies[0], this.node, 5, Enemy); + this.spawnTimer = new GameTimer(5); + } + + public gameTick(deltaTime: number): void { + this.spawnTimer.gameTick(deltaTime); + if (this.spawnTimer.tryFinishPeriod()) { + this.spawnNewEnemy(); + } + } + + private spawnNewEnemy(): void { + const enemy = this.enemyPool.borrow(); + enemy.node.active = true; + enemy.node.setPosition(new Vec3(randomRange(-300, 300), randomRange(-300, 300))); + + enemy.setup(); + + enemy.DeathEvent.on(this.returnEnemyToPool, this); + } + + private returnEnemyToPool(enemy: Enemy): void { + console.log("Return to enemy pool"); + enemy.DeathEvent.off(this.returnEnemyToPool); + this.enemyPool.return(enemy); + } +} diff --git a/assets/Scripts/Game/Enemy/EnemySpawner.ts.meta b/assets/Scripts/Game/Enemy/EnemySpawner.ts.meta new file mode 100644 index 0000000..1bb9c7f --- /dev/null +++ b/assets/Scripts/Game/Enemy/EnemySpawner.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "8aa2a393-cd51-4bb4-a979-095e6fce95a9", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/GameBootstrapper.ts b/assets/Scripts/Game/GameBootstrapper.ts new file mode 100644 index 0000000..b0031c1 --- /dev/null +++ b/assets/Scripts/Game/GameBootstrapper.ts @@ -0,0 +1,34 @@ +import { Component, _decorator } from "cc"; +import { PlayerCollisionSystem } from "./Collision/PlayerCollisionSystem"; +import { WeaponCollisionSystem } from "./Collision/WeaponCollisionSystem"; +import { EnemySpawner } from "./Enemy/EnemySpawner"; +import { VirtualJoystic } from "./Input/VirtualJoystic"; +import { Player } from "./Player/Player"; +import { Weapon } from "./Weapon"; +const { ccclass, property } = _decorator; + +@ccclass("GameBootstrapper") +export class GameBootstrapper extends Component { + @property(VirtualJoystic) private virtualJoystic: VirtualJoystic; + @property(Player) private player: Player; + @property(Weapon) private weapon: Weapon; + @property(EnemySpawner) private enemySpawner: EnemySpawner; + @property(Number) private strikeDelay = 0; + @property(Number) private collisionDelay = 0; + private playerCollisionSystem: PlayerCollisionSystem; + + public start(): void { + this.virtualJoystic.init(); + this.weapon.init(this.strikeDelay); + this.player.init(this.virtualJoystic, this.weapon, 50); + this.enemySpawner.init(); + this.playerCollisionSystem = new PlayerCollisionSystem(this.player, this.collisionDelay); + new WeaponCollisionSystem(this.weapon); + } + + public update(deltaTime: number): void { + this.player.gameTick(deltaTime); + this.playerCollisionSystem.gameTick(deltaTime); + this.enemySpawner.gameTick(deltaTime); + } +} diff --git a/assets/Scripts/GameBootstrapper.ts.meta b/assets/Scripts/Game/GameBootstrapper.ts.meta similarity index 100% rename from assets/Scripts/GameBootstrapper.ts.meta rename to assets/Scripts/Game/GameBootstrapper.ts.meta diff --git a/assets/Scripts/Game/GroupType.ts b/assets/Scripts/Game/GroupType.ts new file mode 100644 index 0000000..4e9887e --- /dev/null +++ b/assets/Scripts/Game/GroupType.ts @@ -0,0 +1,8 @@ +// Flags, shift must match index in ProjectSettings > Physics + +export enum GroupType { + DEFAULT = 1 << 0, + PLAYER = 1 << 1, + ENEMY = 1 << 2, + WEAPON = 1 << 3 +} diff --git a/assets/Scripts/Game/GroupType.ts.meta b/assets/Scripts/Game/GroupType.ts.meta new file mode 100644 index 0000000..50dc441 --- /dev/null +++ b/assets/Scripts/Game/GroupType.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "99f179ea-aaed-4e55-9e65-b4d5e45fc997", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/Input.meta b/assets/Scripts/Game/Input.meta new file mode 100644 index 0000000..1b789c3 --- /dev/null +++ b/assets/Scripts/Game/Input.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "7a57756d-1dfb-4d05-adfd-1401435d75f6", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/Scripts/VirtualJoystic.ts b/assets/Scripts/Game/Input/VirtualJoystic.ts similarity index 100% rename from assets/Scripts/VirtualJoystic.ts rename to assets/Scripts/Game/Input/VirtualJoystic.ts diff --git a/assets/Scripts/VirtualJoystic.ts.meta b/assets/Scripts/Game/Input/VirtualJoystic.ts.meta similarity index 100% rename from assets/Scripts/VirtualJoystic.ts.meta rename to assets/Scripts/Game/Input/VirtualJoystic.ts.meta diff --git a/assets/Scripts/Game/Player.meta b/assets/Scripts/Game/Player.meta new file mode 100644 index 0000000..8ee04e9 --- /dev/null +++ b/assets/Scripts/Game/Player.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "3697ba4f-16f0-4a2d-9330-47c472df973a", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/Scripts/Player.ts b/assets/Scripts/Game/Player/Player.ts similarity index 67% rename from assets/Scripts/Player.ts rename to assets/Scripts/Game/Player/Player.ts index a985429..1cb39e9 100644 --- a/assets/Scripts/Player.ts +++ b/assets/Scripts/Game/Player/Player.ts @@ -1,22 +1,33 @@ import { BoxCollider2D, Collider2D, Component, Vec2, Vec3, _decorator } from "cc"; -import { VirtualJoystic } from "./VirtualJoystic"; -import { Weapon } from "./Weapon"; +import { VirtualJoystic } from "../Input/VirtualJoystic"; +import { Weapon } from "../Weapon"; +import { UnitHealth } from "./UnitHealth"; +import { PlayerUI } from "./PlayerUI/PlayerUI"; const { ccclass, property } = _decorator; @ccclass("Player") export class Player extends Component { @property private speed = 0; @property(BoxCollider2D) private collider: BoxCollider2D; + @property(PlayerUI) private playerUI: PlayerUI; private virtualJoystic: VirtualJoystic; private weapon: Weapon; + private health: UnitHealth; - public init(virtualJoystic: VirtualJoystic, weapon: Weapon): void { + public init(virtualJoystic: VirtualJoystic, weapon: Weapon, maxHp: number): void { this.virtualJoystic = virtualJoystic; this.weapon = weapon; + this.health = new UnitHealth(maxHp); this.weapon.node.parent = this.node; this.weapon.node.setPosition(new Vec3()); + + this.playerUI.init(this.health); + } + + public get Health(): UnitHealth { + return this.health; } public get Collider(): Collider2D { diff --git a/assets/Scripts/Player.ts.meta b/assets/Scripts/Game/Player/Player.ts.meta similarity index 100% rename from assets/Scripts/Player.ts.meta rename to assets/Scripts/Game/Player/Player.ts.meta diff --git a/assets/Scripts/Game/Player/PlayerUI.meta b/assets/Scripts/Game/Player/PlayerUI.meta new file mode 100644 index 0000000..88f0d2a --- /dev/null +++ b/assets/Scripts/Game/Player/PlayerUI.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "82d14029-0ea6-4de6-b796-05339d2d19b1", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/Scripts/Game/Player/PlayerUI/PlayerHealthUI.ts b/assets/Scripts/Game/Player/PlayerUI/PlayerHealthUI.ts new file mode 100644 index 0000000..8d9bfa2 --- /dev/null +++ b/assets/Scripts/Game/Player/PlayerUI/PlayerHealthUI.ts @@ -0,0 +1,19 @@ +import { Component, ProgressBar, _decorator } from "cc"; +import { UnitHealth } from "../UnitHealth"; +const { ccclass, property } = _decorator; + +@ccclass("PlayerHealthUI") +export class PlayerHealthUI extends Component { + @property(ProgressBar) public healthBar: ProgressBar; + private health: UnitHealth; + + public init(health: UnitHealth): void { + this.healthBar.progress = 1; + this.health = health; + this.health.HealthPointsChangeEvent.on(this.updateHealthBar, this); + } + + private updateHealthBar(): void { + this.healthBar.progress = this.health.HealthPoints / this.health.MaxHealthPoints; + } +} diff --git a/assets/Scripts/Game/Player/PlayerUI/PlayerHealthUI.ts.meta b/assets/Scripts/Game/Player/PlayerUI/PlayerHealthUI.ts.meta new file mode 100644 index 0000000..18c4e6f --- /dev/null +++ b/assets/Scripts/Game/Player/PlayerUI/PlayerHealthUI.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "84a1c057-2ef8-4ead-8903-5753f36ac735", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/Player/PlayerUI/PlayerUI.ts b/assets/Scripts/Game/Player/PlayerUI/PlayerUI.ts new file mode 100644 index 0000000..fc86ecd --- /dev/null +++ b/assets/Scripts/Game/Player/PlayerUI/PlayerUI.ts @@ -0,0 +1,13 @@ +import { Component, _decorator } from "cc"; +import { UnitHealth } from "../UnitHealth"; +import { PlayerHealthUI } from "./PlayerHealthUI"; +const { ccclass, property } = _decorator; + +@ccclass("PlayerUI") +export class PlayerUI extends Component { + @property(PlayerHealthUI) private healthUI: PlayerHealthUI; + + public init(playerHealth: UnitHealth): void { + this.healthUI.init(playerHealth); + } +} diff --git a/assets/Scripts/Game/Player/PlayerUI/PlayerUI.ts.meta b/assets/Scripts/Game/Player/PlayerUI/PlayerUI.ts.meta new file mode 100644 index 0000000..3efcc00 --- /dev/null +++ b/assets/Scripts/Game/Player/PlayerUI/PlayerUI.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "634f676f-c335-42a2-85e8-f214e9ce5eb7", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/Player/UnitHealth.ts b/assets/Scripts/Game/Player/UnitHealth.ts new file mode 100644 index 0000000..3791356 --- /dev/null +++ b/assets/Scripts/Game/Player/UnitHealth.ts @@ -0,0 +1,42 @@ +import { ISignal } from "../../Services/EventSystem/ISignal"; +import { Signal } from "../../Services/EventSystem/Signal"; + +export class UnitHealth { + private healthPoints: number; + private maxHealthPoints: number; + private healthPointsChangeEvent: Signal = new Signal(); + + public constructor(maxHealth: number) { + this.maxHealthPoints = maxHealth; + this.healthPoints = maxHealth; + } + + public get IsAlive(): boolean { + return 0 < this.healthPoints; + } + + public get HealthPoints(): number { + return this.healthPoints; + } + public get MaxHealthPoints(): number { + return this.maxHealthPoints; + } + + public get HealthPointsChangeEvent(): ISignal { + return this.healthPointsChangeEvent; + } + + public heal(points: number): void { + this.healthPoints = Math.min(this.maxHealthPoints, this.healthPoints + points); + this.healthPointsChangeEvent.trigger(this.healthPoints); + } + + public damage(points: number): void { + this.healthPoints -= points; + this.healthPointsChangeEvent.trigger(this.healthPoints); + } + + public setMaxHealth(maxHealth: number): void { + this.maxHealthPoints = maxHealth; + } +} diff --git a/assets/Scripts/Game/Player/UnitHealth.ts.meta b/assets/Scripts/Game/Player/UnitHealth.ts.meta new file mode 100644 index 0000000..cf31960 --- /dev/null +++ b/assets/Scripts/Game/Player/UnitHealth.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "8118806a-dc7c-4e94-84c2-b0a95be43209", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Weapon.ts b/assets/Scripts/Game/Weapon.ts similarity index 75% rename from assets/Scripts/Weapon.ts rename to assets/Scripts/Game/Weapon.ts index cf4666a..8052ff6 100644 --- a/assets/Scripts/Weapon.ts +++ b/assets/Scripts/Game/Weapon.ts @@ -1,4 +1,5 @@ import { Animation, BoxCollider2D, Collider2D, Component, Vec2, Vec3, _decorator } from "cc"; +import { GameTimer } from "../Services/GameTimer"; const { ccclass, property } = _decorator; @ccclass("Weapon") @@ -6,17 +7,15 @@ export class Weapon extends Component { @property(Animation) private weaponAnimation: Animation; @property(BoxCollider2D) private collider: BoxCollider2D; - private strikeDelay: number; - private currentDelay = 0; + private strikeTimer: GameTimer; public init(strikeDelay: number): void { - this.strikeDelay = strikeDelay; + this.strikeTimer = new GameTimer(strikeDelay); } public gameTick(deltaTime: number, movement: Vec2): void { - this.currentDelay += deltaTime; - if (this.strikeDelay / 4 <= this.currentDelay) { - this.currentDelay = 0; + this.strikeTimer.gameTick(deltaTime); + if (this.strikeTimer.tryFinishPeriod()) { this.strike(movement); } } @@ -25,6 +24,10 @@ export class Weapon extends Component { return this.collider; } + public get Damage(): number { + return 5; + } + private strike(movement: Vec2): void { const direction: Vec2 = movement.normalize(); const angle: number = (Math.atan2(direction.y, direction.x) * 180) / Math.PI; diff --git a/assets/Scripts/Weapon.ts.meta b/assets/Scripts/Game/Weapon.ts.meta similarity index 100% rename from assets/Scripts/Weapon.ts.meta rename to assets/Scripts/Game/Weapon.ts.meta diff --git a/assets/Scripts/GameBootstrapper.ts b/assets/Scripts/GameBootstrapper.ts deleted file mode 100644 index d622cc6..0000000 --- a/assets/Scripts/GameBootstrapper.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Component, instantiate, Prefab, random, randomRange, Vec3, _decorator } from "cc"; -import { CollisionSystem } from "./CollisionSystem"; -import { Enemy } from "./Enemy"; -import { Player } from "./Player"; -import { ObjectPool } from "./Services/ObjectPool"; -import { VirtualJoystic } from "./VirtualJoystic"; -import { Weapon } from "./Weapon"; -const { ccclass, property } = _decorator; - -@ccclass("GameBootstrapper") -export class GameBootstrapper extends Component { - @property(VirtualJoystic) private virtualJoystic: VirtualJoystic; - @property(Player) private player: Player; - @property(Weapon) private weapon: Weapon; - @property(Prefab) private enemy: Prefab; - @property(Number) private strikeDelay = 0; - - public start(): void { - this.virtualJoystic.init(); - this.weapon.init(this.strikeDelay); - this.player.init(this.virtualJoystic, this.weapon); - - new CollisionSystem(this.player, this.weapon); - - const op: ObjectPool = new ObjectPool(this.enemy, this.node, 10, Player); - - const borrowed: Player[] = []; - for (let index = 0; index < 7; index++) { - const enemy: Player = op.borrow(); - enemy.node.parent = this.node; - enemy.node.active = true; - enemy.node.setPosition(new Vec3(randomRange(-200, 200))); - - if (index < 5) borrowed.push(enemy); - } - - borrowed.forEach((borrowedEnemy) => { - op.return(borrowedEnemy); - }); - } - - public update(deltaTime: number): void { - this.player.gameTick(deltaTime); - } - - public getEnemy(): T { - const i = instantiate(this.enemy); - i.parent = this.node; - return i.getComponent(Enemy.name); - } -} diff --git a/assets/Scripts/Services.meta b/assets/Scripts/Services.meta index 1c1769f..b635787 100644 --- a/assets/Scripts/Services.meta +++ b/assets/Scripts/Services.meta @@ -2,7 +2,7 @@ "ver": "1.1.0", "importer": "directory", "imported": true, - "uuid": "cebf49b9-55bd-4829-bb97-cb8bd1378a21", + "uuid": "43b42e2e-f3c3-4174-bd1f-d268a2e8c53a", "files": [], "subMetas": {}, "userData": { diff --git a/assets/Scripts/Services/EventSystem/ISignal.ts b/assets/Scripts/Services/EventSystem/ISignal.ts index 982be7f..a6eebca 100644 --- a/assets/Scripts/Services/EventSystem/ISignal.ts +++ b/assets/Scripts/Services/EventSystem/ISignal.ts @@ -1,4 +1,4 @@ export interface ISignal { - on(handler: (data: T) => void): void; + on(handler: (data: T) => void, thisArg: any): void; off(handler: (data: T) => void): void; } diff --git a/assets/Scripts/Services/EventSystem/Signal.ts b/assets/Scripts/Services/EventSystem/Signal.ts index e5e7a0b..bcbdf74 100644 --- a/assets/Scripts/Services/EventSystem/Signal.ts +++ b/assets/Scripts/Services/EventSystem/Signal.ts @@ -2,15 +2,23 @@ import { ISignal } from "./ISignal"; export class Signal implements ISignal { private handlers: ((data: T) => void)[] = []; + private thisArgs: any[] = []; - public on(handler: (data: T) => void): void { + public on(handler: (data: T) => void, thisArg: any): void { this.handlers.push(handler); + this.thisArgs.push(thisArg); } public off(handler: (data: T) => void): void { + console.log("[OFF] " + this.handlers.length); this.handlers = this.handlers.filter((h) => h !== handler); + console.log("[OFF] >> " + this.handlers.length); } public trigger(data: T): void { - [...this.handlers].forEach((handler) => handler(data)); + //[...this.handlers].forEach((handler) => handler(data)); + + for (let i = 0; i < this.handlers.length; i++) { + this.handlers[i].call(this.thisArgs[i], data); + } } } diff --git a/assets/Scripts/Services/GameTimer.ts b/assets/Scripts/Services/GameTimer.ts new file mode 100644 index 0000000..6014733 --- /dev/null +++ b/assets/Scripts/Services/GameTimer.ts @@ -0,0 +1,21 @@ +export class GameTimer { + private targetDelay: number; + private currentDelay = 0; + + public constructor(targetDelay: number) { + this.targetDelay = targetDelay; + } + + public gameTick(deltaTime: number): void { + this.currentDelay += deltaTime; + } + + public tryFinishPeriod(): boolean { + if (this.targetDelay <= this.currentDelay) { + this.currentDelay = 0; + return true; + } else { + return false; + } + } +} diff --git a/assets/Scripts/Services/GameTimer.ts.meta b/assets/Scripts/Services/GameTimer.ts.meta new file mode 100644 index 0000000..b3b5fe5 --- /dev/null +++ b/assets/Scripts/Services/GameTimer.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "930242d8-1406-4fe0-9dd7-6b700ecff471", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Services/UI.meta b/assets/Scripts/Services/UI.meta new file mode 100644 index 0000000..45cfdeb --- /dev/null +++ b/assets/Scripts/Services/UI.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "de96cc65-e1ab-47ec-b1c5-74cd116d4dc4", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/Scripts/Services/Utils.meta b/assets/Scripts/Services/Utils.meta new file mode 100644 index 0000000..acff897 --- /dev/null +++ b/assets/Scripts/Services/Utils.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.1.0", + "importer": "directory", + "imported": true, + "uuid": "9f621aea-cba9-4ef2-82af-6fae7a3a0fb7", + "files": [], + "subMetas": {}, + "userData": { + "compressionType": {}, + "isRemoteBundle": {} + } +} diff --git a/assets/Scripts/Services/Utils/AsyncUtils.ts b/assets/Scripts/Services/Utils/AsyncUtils.ts new file mode 100644 index 0000000..de8fee4 --- /dev/null +++ b/assets/Scripts/Services/Utils/AsyncUtils.ts @@ -0,0 +1,3 @@ +export async function delay(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/assets/Scripts/Services/Utils/AsyncUtils.ts.meta b/assets/Scripts/Services/Utils/AsyncUtils.ts.meta new file mode 100644 index 0000000..531c7b5 --- /dev/null +++ b/assets/Scripts/Services/Utils/AsyncUtils.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "a920e5e1-f469-4f4b-ad81-fa27d49f0389", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/settings/v2/packages/project.json b/settings/v2/packages/project.json new file mode 100644 index 0000000..f00e93e --- /dev/null +++ b/settings/v2/packages/project.json @@ -0,0 +1,24 @@ +{ + "physics": { + "collisionGroups": [ + { + "index": 1, + "name": "PLAYER" + }, + { + "index": 2, + "name": "ENEMY" + }, + { + "index": 3, + "name": "WEAPON" + } + ], + "collisionMatrix": { + "0": 0, + "1": 4, + "2": 10, + "3": 4 + } + } +}