diff --git a/assets/Data/GameSettings.json b/assets/Data/GameSettings.json index 1a2def9..7c4c31c 100644 --- a/assets/Data/GameSettings.json +++ b/assets/Data/GameSettings.json @@ -67,22 +67,23 @@ "health": 1, "damage": 1, "speed": 50 + }, + { + "id": "Wave", + "moveType": "Launch", + "health": 1, + "damage": 1, + "speed": 100 } ], - "waveEnemySpawner": { - "cooldown": 5, - "enemiesPerWave": 30, - "waveLifetime": 20, - "enemyId": "Basic" - }, "waveEnemySpawners": [ { - "cooldown": 0, - "enemiesPerWave": 0, - "waveLifetime": 0, - "enemyName": "", - "enemyMoveType": "", - "enemyType": "" + "startDelay": 0, + "stopDelay": 100, + "cooldown": 5, + "enemiesPerWave": 30, + "waveLifetime": 20, + "enemyId": "Wave" } ] } diff --git a/assets/Scripts/Game/Data/GameSettings.ts b/assets/Scripts/Game/Data/GameSettings.ts index f8d99a3..0c05d99 100644 --- a/assets/Scripts/Game/Data/GameSettings.ts +++ b/assets/Scripts/Game/Data/GameSettings.ts @@ -50,11 +50,12 @@ export class UpgradeSettings { export class EnemyManagerSettings { public enemies: EnemySettings[] = [new EnemySettings()]; - public waveEnemySpawner = new WaveEnemySpawnerSettings(); public waveEnemySpawners: WaveEnemySpawnerSettings[] = [new WaveEnemySpawnerSettings()]; } export class WaveEnemySpawnerSettings { + public startDelay = 0; + public stopDelay = 0; public cooldown = 0; public enemiesPerWave = 0; public waveLifetime = 0; diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts b/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts index a06c764..ebefc1f 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts @@ -8,6 +8,7 @@ import { FollowTargetEnemyMover } from "./EnemyMover/FollowTargetEnemyMover"; import { PeriodicFollowTargetEnemyMover } from "./EnemyMover/PeriodicFollowTargetEnemyMover"; import { WaveEnemyMover } from "./EnemyMover/WaveEnemyMover"; import { CircularEnemySpawner } from "./EnemySpawner/CircularEnemySpawner"; +import { DelayedEnemySpawner } from "./EnemySpawner/DelayedEnemySpawner"; import { EnemySpawner } from "./EnemySpawner/EnemySpawner"; import { IndividualEnemySpawner } from "./EnemySpawner/IndividualEnemySpawner"; import { WaveEnemySpawner } from "./EnemySpawner/WaveEnemySpawner"; @@ -21,18 +22,23 @@ export class EnemyManager extends Component { private movementTypeToMover: Map = new Map(); + private spawners: DelayedEnemySpawner[] = []; + private individualEnemySpawner: IndividualEnemySpawner; private circularEnemySpawner: CircularEnemySpawner; - private waveEnemySpawner: WaveEnemySpawner; public init(targetNode: Node, settings: EnemyManagerSettings): void { this.enemySpawner.init(targetNode, settings.enemies); this.enemySpawner.EnemyAddedEvent.on(this.onEnemyAdded, this); this.enemySpawner.enemyRemovedEvent.on(this.onRemoveEnemy, this); - this.individualEnemySpawner = new IndividualEnemySpawner(this.enemySpawner, "Basic"); - this.circularEnemySpawner = new CircularEnemySpawner(this.enemySpawner, 30, "Basic"); - this.waveEnemySpawner = new WaveEnemySpawner(this.enemySpawner, settings.waveEnemySpawner); + for (const waveSpawnerSettings of settings.waveEnemySpawners) { + const waveSpawner = new WaveEnemySpawner(this.enemySpawner, waveSpawnerSettings); + this.spawners.push(waveSpawner); + } + + this.individualEnemySpawner = new IndividualEnemySpawner(this.enemySpawner, "Basic", 0); + this.circularEnemySpawner = new CircularEnemySpawner(this.enemySpawner, 30, "Basic", 5); this.movementTypeToMover.set(EnemyMovementType.Follow, new FollowTargetEnemyMover(targetNode)); this.movementTypeToMover.set(EnemyMovementType.Launch, new WaveEnemyMover(targetNode)); @@ -44,7 +50,10 @@ export class EnemyManager extends Component { public gameTick(deltaTime: number): void { this.individualEnemySpawner.gameTick(deltaTime); this.circularEnemySpawner.gameTick(deltaTime); - this.waveEnemySpawner.gameTick(deltaTime); + + for (const spawner of this.spawners) { + spawner.gameTick(deltaTime); + } for (const kvp of this.movementTypeToMover) { kvp[1].gameTick(deltaTime); diff --git a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/CircularEnemySpawner.ts b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/CircularEnemySpawner.ts index 1e9c89b..2ddce89 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/CircularEnemySpawner.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/CircularEnemySpawner.ts @@ -1,13 +1,17 @@ import { GameTimer } from "../../../../Services/GameTimer"; import { roundToOneDecimal } from "../../../../Services/Utils/MathUtils"; + +import { DelayedEnemySpawner } from "./DelayedEnemySpawner"; import { EnemySpawner } from "./EnemySpawner"; -export class CircularEnemySpawner { +export class CircularEnemySpawner extends DelayedEnemySpawner { private spawnTimer: GameTimer = new GameTimer(10); - public constructor(private enemySpawner: EnemySpawner, private enemiesToSpawn: number, private enemyId: string) {} + public constructor(private enemySpawner: EnemySpawner, private enemiesToSpawn: number, private enemyId: string, startDelay = 0, stopDelay = 100) { + super(startDelay, stopDelay); + } - public gameTick(deltaTime: number): void { + public delayedGameTick(deltaTime: number): void { this.spawnTimer.gameTick(deltaTime); if (this.spawnTimer.tryFinishPeriod()) { diff --git a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/DelayedEnemySpawner.ts b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/DelayedEnemySpawner.ts new file mode 100644 index 0000000..fb59d7b --- /dev/null +++ b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/DelayedEnemySpawner.ts @@ -0,0 +1,13 @@ +export abstract class DelayedEnemySpawner { + private currentTime = 0; + public constructor(private startDelay: number, private stopDelay: number) {} + + public gameTick(deltaTime: number): void { + this.currentTime += deltaTime; + if (this.startDelay <= this.currentTime && this.currentTime <= this.stopDelay) { + this.delayedGameTick(deltaTime); + } + } + + public abstract delayedGameTick(deltaTime: number): void; +} diff --git a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/DelayedEnemySpawner.ts.meta b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/DelayedEnemySpawner.ts.meta new file mode 100644 index 0000000..8778396 --- /dev/null +++ b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/DelayedEnemySpawner.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "98291995-7dbb-40da-bce6-4ca9dd7cc45f", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/EnemySpawner.ts b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/EnemySpawner.ts index 9396bcb..0580112 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/EnemySpawner.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/EnemySpawner.ts @@ -4,7 +4,6 @@ import { Signal } from "../../../../Services/EventSystem/Signal"; import { ObjectPool } from "../../../../Services/ObjectPool"; import { EnemySettings } from "../../../Data/GameSettings"; import { Enemy } from "../Enemy"; -import { EnemyMovementType } from "../EnemyMovementType"; const { ccclass, property } = _decorator; diff --git a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/IndividualEnemySpawner.ts b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/IndividualEnemySpawner.ts index 2c1b7a4..9bd0c2b 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/IndividualEnemySpawner.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/IndividualEnemySpawner.ts @@ -1,14 +1,17 @@ import { randomRange } from "cc"; import { GameTimer } from "../../../../Services/GameTimer"; import { randomPositiveOrNegative } from "../../../../Services/Utils/MathUtils"; +import { DelayedEnemySpawner } from "./DelayedEnemySpawner"; import { EnemySpawner } from "./EnemySpawner"; -export class IndividualEnemySpawner { +export class IndividualEnemySpawner extends DelayedEnemySpawner { private spawnTimer: GameTimer = new GameTimer(1); - public constructor(private enemySpawner: EnemySpawner, private enemyId: string) {} + public constructor(private enemySpawner: EnemySpawner, private enemyId: string, startDelay = 0, stopDelay = 100) { + super(startDelay, stopDelay); + } - public gameTick(deltaTime: number): void { + public delayedGameTick(deltaTime: number): void { this.spawnTimer.gameTick(deltaTime); if (this.spawnTimer.tryFinishPeriod()) { const posX: number = randomRange(300, 600) * randomPositiveOrNegative(); diff --git a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/WaveEnemySpawner.ts b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/WaveEnemySpawner.ts index 57d7174..b32d99f 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/WaveEnemySpawner.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/WaveEnemySpawner.ts @@ -3,9 +3,10 @@ import { GameTimer } from "../../../../Services/GameTimer"; import { randomPositiveOrNegative } from "../../../../Services/Utils/MathUtils"; import { WaveEnemySpawnerSettings } from "../../../Data/GameSettings"; import { Enemy } from "../Enemy"; +import { DelayedEnemySpawner } from "./DelayedEnemySpawner"; import { EnemySpawner } from "./EnemySpawner"; -export class WaveEnemySpawner { +export class WaveEnemySpawner extends DelayedEnemySpawner { private enemiesPerWave: number; private waveLifetime: number; private enemyId: string; @@ -14,13 +15,15 @@ export class WaveEnemySpawner { private waves: EnemyWave[] = []; public constructor(private enemySpawner: EnemySpawner, settings: WaveEnemySpawnerSettings) { + super(settings.startDelay, settings.stopDelay); + this.spawnTimer = new GameTimer(settings.cooldown); this.enemiesPerWave = settings.enemiesPerWave; this.waveLifetime = settings.waveLifetime; this.enemyId = settings.enemyId; } - public gameTick(deltaTime: number): void { + public delayedGameTick(deltaTime: number): void { this.spawnTimer.gameTick(deltaTime); this.tryRemoveExpiredEnemies(deltaTime);