From 8aa7ee6f2e427d734c504fe9a8e1b45f5b83c815 Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 5 Dec 2022 12:19:46 +0100 Subject: [PATCH] Enemy spawners --- assets/Scripts/Game/GameBootstrapper.ts | 3 --- .../Game/Unit/Enemy/CircularEnemySpawner.ts | 22 +++++++++++++++ .../Unit/Enemy/CircularEnemySpawner.ts.meta | 9 +++++++ assets/Scripts/Game/Unit/Enemy/Enemy.ts | 8 ++---- .../Scripts/Game/Unit/Enemy/EnemyManager.ts | 18 ++++++++++--- assets/Scripts/Game/Unit/Enemy/EnemyMover.ts | 2 +- .../Scripts/Game/Unit/Enemy/EnemySpawner.ts | 27 +++++++++---------- assets/Scripts/Game/Unit/Enemy/EnemyType.ts | 3 +++ .../Scripts/Game/Unit/Enemy/EnemyType.ts.meta | 9 +++++++ .../Game/Unit/Enemy/InvididualEnemySpawner.ts | 18 +++++++++++++ .../Unit/Enemy/InvididualEnemySpawner.ts.meta | 9 +++++++ assets/Scripts/Services/Utils/MathUtils.ts | 4 +++ 12 files changed, 104 insertions(+), 28 deletions(-) create mode 100644 assets/Scripts/Game/Unit/Enemy/CircularEnemySpawner.ts create mode 100644 assets/Scripts/Game/Unit/Enemy/CircularEnemySpawner.ts.meta create mode 100644 assets/Scripts/Game/Unit/Enemy/EnemyType.ts create mode 100644 assets/Scripts/Game/Unit/Enemy/EnemyType.ts.meta create mode 100644 assets/Scripts/Game/Unit/Enemy/InvididualEnemySpawner.ts create mode 100644 assets/Scripts/Game/Unit/Enemy/InvididualEnemySpawner.ts.meta diff --git a/assets/Scripts/Game/GameBootstrapper.ts b/assets/Scripts/Game/GameBootstrapper.ts index 80a0040..9c72c9f 100644 --- a/assets/Scripts/Game/GameBootstrapper.ts +++ b/assets/Scripts/Game/GameBootstrapper.ts @@ -59,7 +59,6 @@ export class GameBootstrapper extends Component { this.player.node, settings.player.haloLauncher ); - this.haloProjectileLauncher.upgrade(); this.horizontalProjectileLauncher = new WaveProjectileLauncher( this.horizontalProjectileLauncherComponent, @@ -67,7 +66,6 @@ export class GameBootstrapper extends Component { [new Vec2(-1, 0), new Vec2(1, 0)], settings.player.horizontalLauncher ); - this.horizontalProjectileLauncher.upgrade(); this.diagonalProjectileLauncher = new WaveProjectileLauncher( this.diagonalProjectileLauncherComponent, @@ -75,7 +73,6 @@ export class GameBootstrapper extends Component { [new Vec2(-0.5, -0.5), new Vec2(0.5, -0.5)], settings.player.diagonalLauncher ); - this.diagonalProjectileLauncher.upgrade(); new PlayerProjectileCollisionSystem([this.haloProjectileLauncher, this.horizontalProjectileLauncher, this.diagonalProjectileLauncher]); diff --git a/assets/Scripts/Game/Unit/Enemy/CircularEnemySpawner.ts b/assets/Scripts/Game/Unit/Enemy/CircularEnemySpawner.ts new file mode 100644 index 0000000..d031a79 --- /dev/null +++ b/assets/Scripts/Game/Unit/Enemy/CircularEnemySpawner.ts @@ -0,0 +1,22 @@ +import { GameTimer } from "../../../Services/GameTimer"; +import { roundToOneDecimal } from "../../../Services/Utils/MathUtils"; +import { EnemySpawner } from "./EnemySpawner"; +import { EnemyType } from "./EnemyType"; + +export class CircularEnemySpawner { + private spawnTimer: GameTimer = new GameTimer(10); + public constructor(private enemySpawner: EnemySpawner, private enemiesToSpawn: number, private enemyType: EnemyType) {} + public gameTick(deltaTime: number): void { + this.spawnTimer.gameTick(deltaTime); + + if (this.spawnTimer.tryFinishPeriod()) { + const angle: number = (2 * Math.PI) / this.enemiesToSpawn; + + for (let i = 0; i < this.enemiesToSpawn; i++) { + const posX: number = roundToOneDecimal(Math.sin(angle * i)) * 500; + const posY: number = roundToOneDecimal(Math.cos(angle * i)) * 500; + this.enemySpawner.spawnNewEnemy(posX, posY); + } + } + } +} diff --git a/assets/Scripts/Game/Unit/Enemy/CircularEnemySpawner.ts.meta b/assets/Scripts/Game/Unit/Enemy/CircularEnemySpawner.ts.meta new file mode 100644 index 0000000..96e5d03 --- /dev/null +++ b/assets/Scripts/Game/Unit/Enemy/CircularEnemySpawner.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "2e8e236a-fcdd-4995-aaff-be8802488d8c", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/Unit/Enemy/Enemy.ts b/assets/Scripts/Game/Unit/Enemy/Enemy.ts index 6fdb677..c8c26fe 100644 --- a/assets/Scripts/Game/Unit/Enemy/Enemy.ts +++ b/assets/Scripts/Game/Unit/Enemy/Enemy.ts @@ -6,7 +6,7 @@ import { UnitHealth } from "../UnitHealth"; const { ccclass, property } = _decorator; @ccclass("Enemy") -export class Enemy extends Component implements IDamageDealing { +export class Enemy extends Component { @property(BoxCollider2D) public collider: BoxCollider2D; private health: UnitHealth = new UnitHealth(1); @@ -15,7 +15,7 @@ export class Enemy extends Component implements IDamageDealing { public setup(position: Vec3): void { this.health = new UnitHealth(1); - this.speed = randomRange(0.5, 1); + this.speed = randomRange(40, 90); this.node.setWorldPosition(position); this.node.active = true; } @@ -51,7 +51,3 @@ export class Enemy extends Component implements IDamageDealing { this.node.setWorldPosition(newPosition); } } - -export interface IDamageDealing { - Damage: number; -} diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts b/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts index 846ae2a..7ce8713 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts @@ -1,8 +1,11 @@ import { Component, Node, _decorator } from "cc"; import { XPSpawner } from "../../XP/XPSpawner"; +import { CircularEnemySpawner } from "./CircularEnemySpawner"; import { Enemy } from "./Enemy"; import { EnemyMover } from "./EnemyMover"; import { EnemySpawner } from "./EnemySpawner"; +import { EnemyType } from "./EnemyType"; +import { InvididualEnemySpawner as IndividualEnemySpawner } from "./InvididualEnemySpawner"; const { ccclass, property } = _decorator; @ccclass("EnemyManager") @@ -12,30 +15,39 @@ export class EnemyManager extends Component { private enemyMover: EnemyMover; + private individualEnemySpawner: IndividualEnemySpawner; + private circularEnemySpawner: CircularEnemySpawner; + public init(targetNode: Node): void { this.enemyMover = new EnemyMover(targetNode); this.enemySpawner.init(targetNode); this.enemySpawner.EnemyAddedEvent.on(this.onEnemyAdded, this); + this.enemySpawner.enemyRemovedEvent.on(this.onRemoveEnemy, this); + + this.individualEnemySpawner = new IndividualEnemySpawner(this.enemySpawner, EnemyType.Basic); + this.circularEnemySpawner = new CircularEnemySpawner(this.enemySpawner, 20, EnemyType.Basic); this.xpSpawner.init(); } public gameTick(deltaTime: number): void { - this.enemySpawner.gameTick(deltaTime); + this.individualEnemySpawner.gameTick(deltaTime); + this.circularEnemySpawner.gameTick(deltaTime); this.enemyMover.gameTick(deltaTime); } private onEnemyAdded(enemy: Enemy): void { enemy.DeathEvent.on(this.onEnemyDied, this); - this.enemyMover.addEnemy(enemy); } private onEnemyDied(enemy: Enemy): void { enemy.DeathEvent.off(this.onEnemyDied); - this.xpSpawner.spawnXp(enemy.node.worldPosition, 1); + } + + private onRemoveEnemy(enemy: Enemy): void { this.enemyMover.removeEnemy(enemy); } } diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyMover.ts b/assets/Scripts/Game/Unit/Enemy/EnemyMover.ts index 9ddb3fa..c24f6ff 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemyMover.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemyMover.ts @@ -22,7 +22,7 @@ export class EnemyMover { this.enemies.forEach((enemy) => { let direction: Vec3 = new Vec3(); direction = Vec3.subtract(direction, this.targetNode.worldPosition, enemy.node.worldPosition); - enemy.moveBy(direction.multiplyScalar(deltaTime).normalize()); + enemy.moveBy(direction.normalize().multiplyScalar(deltaTime)); }); } } diff --git a/assets/Scripts/Game/Unit/Enemy/EnemySpawner.ts b/assets/Scripts/Game/Unit/Enemy/EnemySpawner.ts index 3bd859a..7c51db7 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemySpawner.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemySpawner.ts @@ -1,7 +1,6 @@ -import { Component, Prefab, randomRange, Vec3, _decorator, Node } from "cc"; +import { Component, Node, Prefab, Vec3, _decorator } from "cc"; import { ISignal } from "../../../Services/EventSystem/ISignal"; import { Signal } from "../../../Services/EventSystem/Signal"; -import { GameTimer } from "../../../Services/GameTimer"; import { ObjectPool } from "../../../Services/ObjectPool"; import { Enemy } from "./Enemy"; @@ -12,34 +11,30 @@ export class EnemySpawner extends Component { @property(Prefab) private enemies: Prefab[] = []; public enemyAddedEvent: Signal = new Signal(); + public enemyRemovedEvent: Signal = new Signal(); private enemyPool: ObjectPool; - private spawnTimer: GameTimer; private targetNode: Node; public init(targetNode: Node): void { this.targetNode = targetNode; - this.enemyPool = new ObjectPool(this.enemies[0], this.node, 5, "Enemy"); - this.spawnTimer = new GameTimer(1); - } - - public gameTick(deltaTime: number): void { - this.spawnTimer.gameTick(deltaTime); - if (this.spawnTimer.tryFinishPeriod()) { - this.spawnNewEnemy(); - } + this.enemyPool = new ObjectPool(this.enemies[0], this.node, 50, "Enemy"); } public get EnemyAddedEvent(): ISignal { return this.enemyAddedEvent; } - private spawnNewEnemy(): void { + public get EnemyRemovedEvent(): ISignal { + return this.enemyRemovedEvent; + } + + public spawnNewEnemy(positionX: number, positionY: number): void { const enemy = this.enemyPool.borrow(); const spawnPosition = new Vec3(); - spawnPosition.x = this.targetNode.worldPosition.x + randomRange(-300, 300); - spawnPosition.y = this.targetNode.worldPosition.y + randomRange(-800, 800); + spawnPosition.x = this.targetNode.worldPosition.x + positionX; + spawnPosition.y = this.targetNode.worldPosition.y + positionY; enemy.setup(spawnPosition); enemy.DeathEvent.on(this.returnEnemyToPool, this); @@ -50,5 +45,7 @@ export class EnemySpawner extends Component { private returnEnemyToPool(enemy: Enemy): void { enemy.DeathEvent.off(this.returnEnemyToPool); this.enemyPool.return(enemy); + + this.enemyRemovedEvent.trigger(enemy); } } diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyType.ts b/assets/Scripts/Game/Unit/Enemy/EnemyType.ts new file mode 100644 index 0000000..1b1b752 --- /dev/null +++ b/assets/Scripts/Game/Unit/Enemy/EnemyType.ts @@ -0,0 +1,3 @@ +export enum EnemyType { + Basic = "Basic" +} diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyType.ts.meta b/assets/Scripts/Game/Unit/Enemy/EnemyType.ts.meta new file mode 100644 index 0000000..d7cbeac --- /dev/null +++ b/assets/Scripts/Game/Unit/Enemy/EnemyType.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "8db8a72b-543d-4566-8900-7701372634e3", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/Unit/Enemy/InvididualEnemySpawner.ts b/assets/Scripts/Game/Unit/Enemy/InvididualEnemySpawner.ts new file mode 100644 index 0000000..a53dea1 --- /dev/null +++ b/assets/Scripts/Game/Unit/Enemy/InvididualEnemySpawner.ts @@ -0,0 +1,18 @@ +import { randomRange } from "cc"; +import { GameTimer } from "../../../Services/GameTimer"; +import { randomPositiveOrNegative } from "../../../Services/Utils/MathUtils"; +import { EnemySpawner } from "./EnemySpawner"; +import { EnemyType } from "./EnemyType"; + +export class InvididualEnemySpawner { + private spawnTimer: GameTimer = new GameTimer(1); + public constructor(private enemySpawner: EnemySpawner, enemyType: EnemyType) {} + public gameTick(deltaTime: number): void { + this.spawnTimer.gameTick(deltaTime); + if (this.spawnTimer.tryFinishPeriod()) { + const posX: number = randomRange(300, 600) * randomPositiveOrNegative(); + const posY: number = randomRange(300, 600) * randomPositiveOrNegative(); + this.enemySpawner.spawnNewEnemy(posX, posY); + } + } +} diff --git a/assets/Scripts/Game/Unit/Enemy/InvididualEnemySpawner.ts.meta b/assets/Scripts/Game/Unit/Enemy/InvididualEnemySpawner.ts.meta new file mode 100644 index 0000000..75f17e8 --- /dev/null +++ b/assets/Scripts/Game/Unit/Enemy/InvididualEnemySpawner.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "46674857-f5ad-4112-8b5d-c19879117904", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Services/Utils/MathUtils.ts b/assets/Scripts/Services/Utils/MathUtils.ts index 76a2786..32ab8f9 100644 --- a/assets/Scripts/Services/Utils/MathUtils.ts +++ b/assets/Scripts/Services/Utils/MathUtils.ts @@ -1,3 +1,7 @@ export function roundToOneDecimal(num: number): number { return Math.round(num * 10) / 10; } + +export function randomPositiveOrNegative(): number { + return Math.random() < 0.5 ? 1 : -1; +}