diff --git a/assets/Data/GameSettings.json b/assets/Data/GameSettings.json index 681a648..297a350 100644 --- a/assets/Data/GameSettings.json +++ b/assets/Data/GameSettings.json @@ -16,6 +16,7 @@ "speed": 100, "regenerationDelay": 5, "collisionDelay": 0.5, + "magnetDuration": 5, "weapon": { "strikeDelay": 2, "damage": 2 diff --git a/assets/Media/Prefabs/Game/Player.prefab b/assets/Media/Prefabs/Game/Player.prefab index 1d2a98c..4610f17 100644 --- a/assets/Media/Prefabs/Game/Player.prefab +++ b/assets/Media/Prefabs/Game/Player.prefab @@ -33,18 +33,18 @@ ], "_active": true, "_components": [ - { - "__id__": 140 - }, { "__id__": 142 }, { "__id__": 144 + }, + { + "__id__": 146 } ], "_prefab": { - "__id__": 146 + "__id__": 148 }, "_lpos": { "__type__": "cc.Vec3", @@ -2917,10 +2917,13 @@ "_components": [ { "__id__": 137 + }, + { + "__id__": 139 } ], "_prefab": { - "__id__": 139 + "__id__": 141 }, "_lpos": { "__type__": "cc.Vec3", @@ -2962,7 +2965,7 @@ "__id__": 138 }, "tag": 0, - "_group": 1, + "_group": 512, "_density": 1, "_sensor": false, "_friction": 0.2, @@ -2979,6 +2982,26 @@ "__type__": "cc.CompPrefabInfo", "fileId": "2cKwIyAIBAm5fq0pDIOT0e" }, + { + "__type__": "05a1dLKkINNEa04GJK8DVCC", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 136 + }, + "_enabled": true, + "__prefab": { + "__id__": 140 + }, + "collider": { + "__id__": 137 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "a2ie0T3ptE8L/Z7WvEgRs1" + }, { "__type__": "cc.PrefabInfo", "root": { @@ -2998,7 +3021,7 @@ }, "_enabled": false, "__prefab": { - "__id__": 141 + "__id__": 143 }, "_contentSize": { "__type__": "cc.Size", @@ -3025,10 +3048,10 @@ }, "_enabled": true, "__prefab": { - "__id__": 143 + "__id__": 145 }, "collider": { - "__id__": 144 + "__id__": 146 }, "playerUI": { "__id__": 37 @@ -3036,6 +3059,9 @@ "weapon": { "__id__": 133 }, + "magnet": { + "__id__": 139 + }, "playerGraphics": { "__id__": 2 }, @@ -3060,7 +3086,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 145 + "__id__": 147 }, "tag": 0, "_group": 2, diff --git a/assets/Scripts/Game/Collision/MagnetCollisionSystem.ts b/assets/Scripts/Game/Collision/MagnetCollisionSystem.ts new file mode 100644 index 0000000..8ea3a95 --- /dev/null +++ b/assets/Scripts/Game/Collision/MagnetCollisionSystem.ts @@ -0,0 +1,14 @@ +import { Collider2D, Contact2DType } from "cc"; +import { Item } from "../Items/Item"; +import { ItemAttractor } from "../Items/ItemAttractor"; +import { Magnet } from "../Unit/Player/Magnet"; + +export class MagnetCollisionSystem { + public constructor(magnet: Magnet, private itemAttractor: ItemAttractor) { + magnet.Collider.on(Contact2DType.BEGIN_CONTACT, this.onMagnetContactBegin, this); + } + + private onMagnetContactBegin(_selfCollider: Collider2D, otherCollider: Collider2D): void { + this.itemAttractor.addItem(otherCollider.getComponent(Item)); + } +} diff --git a/assets/Scripts/Game/Collision/MagnetCollisionSystem.ts.meta b/assets/Scripts/Game/Collision/MagnetCollisionSystem.ts.meta new file mode 100644 index 0000000..8269625 --- /dev/null +++ b/assets/Scripts/Game/Collision/MagnetCollisionSystem.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "632b80ed-c193-4c84-b571-7f7663bba767", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/Data/GameSettings.ts b/assets/Scripts/Game/Data/GameSettings.ts index a99077b..795689f 100644 --- a/assets/Scripts/Game/Data/GameSettings.ts +++ b/assets/Scripts/Game/Data/GameSettings.ts @@ -14,6 +14,7 @@ export class PlayerSettings { public speed = 0; public regenerationDelay = 0; public collisionDelay = 0; + public magnetDuration = 0; public weapon: WeaponSettings = new WeaponSettings(); public haloLauncher: HaloLauncherSettings = new HaloLauncherSettings(); public horizontalLauncher: WaveLauncherSettings = new WaveLauncherSettings(); diff --git a/assets/Scripts/Game/Game.ts b/assets/Scripts/Game/Game.ts index d07ea9b..bccc94e 100644 --- a/assets/Scripts/Game/Game.ts +++ b/assets/Scripts/Game/Game.ts @@ -3,6 +3,7 @@ import { ModalWindowManager } from "../Services/ModalWindowSystem/ModalWindowMan import { delay } from "../Services/Utils/AsyncUtils"; import { GameAudioAdapter } from "./Audio/GameAudioAdapter"; import { Background } from "./Background/Background"; +import { MagnetCollisionSystem } from "./Collision/MagnetCollisionSystem"; import { PlayerCollisionSystem } from "./Collision/PlayerCollisionSystem"; import { PlayerProjectileCollisionSystem } from "./Collision/PlayerProjectileCollisionSystem"; import { WeaponCollisionSystem } from "./Collision/WeaponCollisionSystem"; @@ -12,6 +13,7 @@ import { UserData } from "./Data/UserData"; import { KeyboardInput } from "./Input/KeyboardInput"; import { MultiInput } from "./Input/MultiInput"; import { VirtualJoystic } from "./Input/VirtualJoystic"; +import { ItemAttractor } from "./Items/ItemAttractor"; import { ItemManager } from "./Items/ItemManager"; import { GameModalLauncher } from "./ModalWIndows/GameModalLauncher"; import { Pauser } from "./Pauser"; @@ -55,6 +57,8 @@ export class Game extends Component { private enemyProjectileLauncher: EnemyProjectileLauncher; + private itemAttractor: ItemAttractor; + private gamePauser: Pauser = new Pauser(); private gameResult: GameResult; @@ -127,6 +131,9 @@ export class Game extends Component { new PlayerProjectileCollisionSystem([this.haloProjectileLauncher, this.horizontalProjectileLauncher, this.diagonalProjectileLauncher]); + this.itemAttractor = new ItemAttractor(this.player.node, 100); + new MagnetCollisionSystem(this.player.Magnet, this.itemAttractor); + const upgrader = new Upgrader( this.player, this.horizontalProjectileLauncher, @@ -178,6 +185,7 @@ export class Game extends Component { this.horizontalProjectileLauncher.gameTick(deltaTime); this.diagonalProjectileLauncher.gameTick(deltaTime); this.enemyProjectileLauncher.gameTick(deltaTime); + this.itemAttractor.gameTick(deltaTime); this.background.gameTick(); this.timeAlive += deltaTime; @@ -199,6 +207,8 @@ export class Game extends Component { playerData.damage = metaUpgrades.getUpgradeValue(MetaUpgradeType.OverallDamage) + settings.weapon.damage; playerData.strikeDelay = settings.weapon.strikeDelay; + playerData.magnetDuration = settings.magnetDuration; + return playerData; } } diff --git a/assets/Scripts/Game/Items/ItemAttractor.ts b/assets/Scripts/Game/Items/ItemAttractor.ts new file mode 100644 index 0000000..2f471a0 --- /dev/null +++ b/assets/Scripts/Game/Items/ItemAttractor.ts @@ -0,0 +1,40 @@ +import { Node, Vec3 } from "cc"; +import { getDirection } from "../../Services/Utils/VecUtils"; +import { Item } from "./Item"; + +export class ItemAttractor { + private items: Item[] = []; + private speedValues: number[] = []; + + public constructor(private playerNode: Node, private speedIncreasePerSecond: number) {} + + public gameTick(deltaTime: number): void { + for (let i = 0; i < this.items.length; i++) { + const direction: Vec3 = getDirection(this.playerNode.worldPosition, this.items[i].node.worldPosition); + const position = this.items[i].node.worldPosition.clone(); + position.x += direction.x * this.speedValues[i] * deltaTime; + position.y += direction.y * this.speedValues[i] * deltaTime; + + this.items[i].node.setWorldPosition(position); + this.speedValues[i] += this.speedIncreasePerSecond * deltaTime; + } + } + + public addItem(item: Item): void { + if (this.items.includes(item)) return; + + item.PickupEvent.on(this.removeItem, this); + + this.items.push(item); + this.speedValues.push(0); + } + + private removeItem(item: Item): void { + item.PickupEvent.off(this.removeItem); + + const index = this.items.indexOf(item); + + this.items.splice(index, 1); + this.speedValues.splice(index, 1); + } +} diff --git a/assets/Scripts/Game/Items/ItemAttractor.ts.meta b/assets/Scripts/Game/Items/ItemAttractor.ts.meta new file mode 100644 index 0000000..09e21bd --- /dev/null +++ b/assets/Scripts/Game/Items/ItemAttractor.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "9d103e35-89f2-4657-baa4-d89ce8d8b7d9", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/Items/ItemManager.ts b/assets/Scripts/Game/Items/ItemManager.ts index 2aa6480..98cb51b 100644 --- a/assets/Scripts/Game/Items/ItemManager.ts +++ b/assets/Scripts/Game/Items/ItemManager.ts @@ -80,7 +80,9 @@ export class ItemManager extends Component { this.player.Health.heal(this.healthPerPotion); } - private activateMagnet(): void {} + private activateMagnet(): void { + this.player.Magnet.activate(); + } private giveRandomSkill(): void {} diff --git a/assets/Scripts/Game/Unit/Player/Magnet.ts b/assets/Scripts/Game/Unit/Player/Magnet.ts new file mode 100644 index 0000000..eacf7be --- /dev/null +++ b/assets/Scripts/Game/Unit/Player/Magnet.ts @@ -0,0 +1,33 @@ +import { _decorator, Component, Node, Collider2D, CircleCollider2D } from "cc"; +import { GameTimer } from "../../../Services/GameTimer"; +const { ccclass, property } = _decorator; + +@ccclass("Magnet") +export class Magnet extends Component { + @property(CircleCollider2D) private collider: CircleCollider2D; + + private timer: GameTimer; + private duration: number; + + public get Collider(): Collider2D { + return this.collider; + } + public init(duration: number): void { + this.duration = duration; + this.node.active = false; + } + + public activate(): void { + this.timer = new GameTimer(this.duration); + this.node.active = true; + } + + public gameTick(deltaTime: number): void { + if (!this.node.active) return; + + this.timer.gameTick(deltaTime); + if (this.timer.tryFinishPeriod()) { + this.node.active = false; + } + } +} diff --git a/assets/Scripts/Game/Unit/Player/Magnet.ts.meta b/assets/Scripts/Game/Unit/Player/Magnet.ts.meta new file mode 100644 index 0000000..ff14716 --- /dev/null +++ b/assets/Scripts/Game/Unit/Player/Magnet.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "05a1d2ca-9083-4d11-ad38-1892bc0d5082", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/Unit/Player/Player.ts b/assets/Scripts/Game/Unit/Player/Player.ts index 750d9a9..d11b6a2 100644 --- a/assets/Scripts/Game/Unit/Player/Player.ts +++ b/assets/Scripts/Game/Unit/Player/Player.ts @@ -3,6 +3,7 @@ import { delay } from "../../../Services/Utils/AsyncUtils"; import { IInput } from "../../Input/IInput"; import { UnitHealth } from "../UnitHealth"; import { UnitLevel } from "../UnitLevel"; +import { Magnet } from "./Magnet"; import { PlayerRegeneration } from "./PlayerRegeneration"; import { PlayerUI } from "./PlayerUI/PlayerUI"; import { Weapon } from "./Weapon/Weapon"; @@ -14,6 +15,7 @@ export class Player extends Component { @property(BoxCollider2D) private collider: BoxCollider2D; @property(PlayerUI) private playerUI: PlayerUI; @property(Weapon) private weapon: Weapon; + @property(Magnet) private magnet: Magnet; @property(Node) private playerGraphics: Node; @property(Animation) private animation: Animation; @property(Sprite) private sprite: Sprite; @@ -34,6 +36,7 @@ export class Player extends Component { this.speed = data.speed; this.weapon.init(data.strikeDelay, data.damage); + this.magnet.init(data.magnetDuration); this.health.HealthPointsChangeEvent.on(this.animateHpChange, this); this.playerUI.init(this.health); } @@ -50,6 +53,10 @@ export class Player extends Component { return this.weapon; } + public get Magnet(): Magnet { + return this.magnet; + } + public get Regeneration(): PlayerRegeneration { return this.regeneration; } @@ -61,6 +68,7 @@ export class Player extends Component { public gameTick(deltaTime: number): void { this.move(deltaTime); this.weapon.gameTick(deltaTime); + this.magnet.gameTick(deltaTime); this.regeneration.gameTick(deltaTime); } @@ -117,4 +125,7 @@ export class PlayerData { // Weapon public strikeDelay = 0; public damage = 0; + + // Magnet + public magnetDuration = 0; } diff --git a/assets/Scripts/Services/Utils/VecUtils.ts b/assets/Scripts/Services/Utils/VecUtils.ts new file mode 100644 index 0000000..873c336 --- /dev/null +++ b/assets/Scripts/Services/Utils/VecUtils.ts @@ -0,0 +1,6 @@ +import { Vec3 } from "cc"; + +export function getDirection(targetPosition: Vec3, sourcePosition: Vec3): Vec3 { + const direction: Vec3 = new Vec3(); + return Vec3.subtract(direction, targetPosition, sourcePosition).normalize(); +} diff --git a/assets/Scripts/Services/Utils/VecUtils.ts.meta b/assets/Scripts/Services/Utils/VecUtils.ts.meta new file mode 100644 index 0000000..87cfaf6 --- /dev/null +++ b/assets/Scripts/Services/Utils/VecUtils.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "067789c3-748f-4643-82af-bd33216eee30", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/settings/v2/packages/project.json b/settings/v2/packages/project.json index 1c2fe5a..6dbb217 100644 --- a/settings/v2/packages/project.json +++ b/settings/v2/packages/project.json @@ -35,12 +35,12 @@ "1": 468, "2": 42, "3": 4, - "4": 2, + "4": 514, "5": 4, "6": 2, "7": 2, "8": 2, - "9": 0 + "9": 16 } }, "general": {