From 2708c119f3f6b67de7718be0d58d3af1618e1096 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 20 Dec 2022 15:17:57 +0100 Subject: [PATCH] Projectile launcher refactoring --- .../EnemyProjectileLauncher.ts | 27 ++++++- .../HaloProjectileLauncher.ts | 13 +++- .../ProjectileLauncher/ProjectileLauncher.ts | 71 +++++-------------- .../WaveProjectileLauncher.ts | 29 +++++++- 4 files changed, 81 insertions(+), 59 deletions(-) diff --git a/assets/Scripts/Game/Unit/Enemy/ProjectileLauncher.cs/EnemyProjectileLauncher.ts b/assets/Scripts/Game/Unit/Enemy/ProjectileLauncher.cs/EnemyProjectileLauncher.ts index 425dbe0..b238895 100644 --- a/assets/Scripts/Game/Unit/Enemy/ProjectileLauncher.cs/EnemyProjectileLauncher.ts +++ b/assets/Scripts/Game/Unit/Enemy/ProjectileLauncher.cs/EnemyProjectileLauncher.ts @@ -1,5 +1,30 @@ +import { Vec3, Node, Vec2 } from "cc"; +import { GameTimer } from "../../../../Services/GameTimer"; import { ProjectileLauncher } from "../../Player/ProjectileLauncher/ProjectileLauncher"; +import { Enemy } from "../Enemy"; +import { EnemyManager } from "../EnemyManager"; export class EnemyProjectileLauncher { - public constructor(private projectileLauncher: ProjectileLauncher) {} + private enemies: Enemy[] = []; + private shootTimer: GameTimer = new GameTimer(3); + + public constructor(private playerNode: Node, private projectileLauncher: ProjectileLauncher, enemyManager: EnemyManager) { + enemyManager.EnemyAddedEvent.on(this.tryAddEnemy, this); + enemyManager.EnemyRemovedEvent.on(this.tryRemoveEnemy, this); + } + + private tryAddEnemy(enemy: Enemy): void { + if (enemy.Id == "BasicEnemy") { + this.enemies.push(); + } + } + + private tryRemoveEnemy(enemy: Enemy): void { + if (enemy.Id == "BasicEnemy") { + const index = this.enemies.indexOf(enemy); + this.enemies.splice(index, 1); + } + } + + public gameTick(deltaTime: number): void {} } diff --git a/assets/Scripts/Game/Unit/Player/ProjectileLauncher/HaloProjectileLauncher.ts b/assets/Scripts/Game/Unit/Player/ProjectileLauncher/HaloProjectileLauncher.ts index 840e69d..2b14049 100644 --- a/assets/Scripts/Game/Unit/Player/ProjectileLauncher/HaloProjectileLauncher.ts +++ b/assets/Scripts/Game/Unit/Player/ProjectileLauncher/HaloProjectileLauncher.ts @@ -5,12 +5,14 @@ import { HaloLauncherSettings } from "../../../Data/GameSettings"; import { ProjectileCollision } from "../../../Projectile/ProjectileCollision"; import { IProjectileCollisionSignaler } from "../../../Projectile/IProjectileCollisionSignaler"; import { ProjectileData, ProjectileLauncher } from "./ProjectileLauncher"; +import { GameTimer } from "../../../../Services/GameTimer"; export class HaloProjectileLauncher implements IProjectileCollisionSignaler { private currentUpgrade = 0; private defaultCooldown = 0; private cooldownDivisorPerUpgrade = 0; private directions: Vec2[] = []; + private fireTimer = new GameTimer(0); public constructor( private launcher: ProjectileLauncher, @@ -29,7 +31,7 @@ export class HaloProjectileLauncher implements IProjectileCollisionSignaler { this.directions.push(new Vec2(x, y).normalize()); } - launcher.init(settings.launcher, projectileData); + launcher.init(settings.launcher.projectileLifetime, settings.launcher.projectileSpeed, projectileData.damage, projectileData.pierces); } public get ProjectileCollisionEvent(): ISignal { @@ -39,11 +41,16 @@ export class HaloProjectileLauncher implements IProjectileCollisionSignaler { public gameTick(deltaTime: number): void { if (this.currentUpgrade == 0) return; - this.launcher.gameTick(deltaTime, this.playerNode.worldPosition, this.directions); + this.launcher.gameTick(deltaTime); + this.fireTimer.gameTick(deltaTime); + + if (this.fireTimer.tryFinishPeriod()) { + this.launcher.fireProjectiles(this.playerNode.worldPosition, this.directions); + } } public upgrade(): void { this.currentUpgrade++; - this.launcher.Cooldown = this.defaultCooldown / (this.cooldownDivisorPerUpgrade * this.currentUpgrade); + this.fireTimer = new GameTimer(this.defaultCooldown / (this.cooldownDivisorPerUpgrade * this.currentUpgrade)); } } diff --git a/assets/Scripts/Game/Unit/Player/ProjectileLauncher/ProjectileLauncher.ts b/assets/Scripts/Game/Unit/Player/ProjectileLauncher/ProjectileLauncher.ts index da81fe5..704af92 100644 --- a/assets/Scripts/Game/Unit/Player/ProjectileLauncher/ProjectileLauncher.ts +++ b/assets/Scripts/Game/Unit/Player/ProjectileLauncher/ProjectileLauncher.ts @@ -1,11 +1,8 @@ -import { _decorator, Component, Node, Prefab, Vec2, Vec3 } from "cc"; +import { _decorator, Component, Prefab, Vec2, Vec3 } 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 { delay } from "../../../../Services/Utils/AsyncUtils"; import { getDegreeAngleFromDirection } from "../../../../Services/Utils/MathUtils"; -import { ProjectileLauncherSettings } from "../../../Data/GameSettings"; import { IProjectileCollisionSignaler } from "../../../Projectile/IProjectileCollisionSignaler"; import { Projectile } from "../../../Projectile/Projectile"; import { ProjectileCollision } from "../../../Projectile/ProjectileCollision"; @@ -15,77 +12,47 @@ const { ccclass, property } = _decorator; export class ProjectileLauncher extends Component implements IProjectileCollisionSignaler { @property(Prefab) private projectilePrefab: Prefab; private projectileCollisionEvent: Signal = new Signal(); - private projectileData: ProjectileData; - private projectilePool: ObjectPool; - private fireTimer: GameTimer; + + private projectileDamage: number; + private projectilePierces: number; private projectileLifetime: number; - private speed: number; - private wavesToShoot: number; - private wavesDelayMs: number; - private cooldown: number; + private projectileSpeed: number; + + private projectilePool: ObjectPool; private projectiles: Projectile[] = []; private directions: Vec2[] = []; private expireTimes: number[] = []; private currentTime = 0; - public get WavesToShoot(): number { - return this.wavesToShoot; - } - - public set WavesToShoot(value: number) { - this.wavesToShoot = value; - } - - public get Cooldown(): number { - return this.cooldown; - } - - public set Cooldown(value: number) { - this.cooldown = value; - this.fireTimer = new GameTimer(this.cooldown); - } - public get ProjectileCollisionEvent(): ISignal { return this.projectileCollisionEvent; } - public init(settings: ProjectileLauncherSettings, projectileData: ProjectileData): void { - this.projectileData = projectileData; - this.projectileLifetime = settings.projectileLifetime; - this.speed = settings.projectileSpeed; - this.wavesToShoot = settings.wavesToShoot; - this.wavesDelayMs = settings.wavesDelayMs; - this.cooldown = settings.cooldown; + public init(projectileLifetime: number, projectileSpeed: number, projectileDamage: number, projectilePierces: number): void { + this.projectileLifetime = projectileLifetime; + this.projectileSpeed = projectileSpeed; + this.projectileDamage = projectileDamage; + this.projectilePierces = projectilePierces; this.projectilePool = new ObjectPool(this.projectilePrefab, this.node, 6, "Projectile"); - this.fireTimer = new GameTimer(this.cooldown); } - public gameTick(deltaTime: number, startPosition: Vec3, fireDirections: Vec2[]): void { + public gameTick(deltaTime: number): void { this.currentTime += deltaTime; - this.fireTimer.gameTick(deltaTime); - if (this.fireTimer.tryFinishPeriod()) { - this.fireProjectiles(startPosition, fireDirections); - } - this.tryRemoveExpiredProjectiles(); this.moveAllProjectiles(deltaTime); } - private async fireProjectiles(startPosition: Vec3, fireDirections: Vec2[]): Promise { - for (let i = 0; i < this.wavesToShoot; i++) { - for (const direction of fireDirections) { - this.fireProjectile(startPosition, direction); - } - - await delay(this.wavesDelayMs); + public fireProjectiles(startPosition: Vec3, fireDirections: Vec2[]): void { + for (const direction of fireDirections) { + this.fireProjectile(startPosition, direction); } } private fireProjectile(startPosition: Vec3, direction: Vec2): void { const projectile: Projectile = this.projectilePool.borrow(); - projectile.init(this.projectileData.damage, this.projectileData.pierces, getDegreeAngleFromDirection(direction.x, direction.y)); + projectile.init(this.projectileDamage, this.projectilePierces, getDegreeAngleFromDirection(direction.x, direction.y)); projectile.node.setWorldPosition(startPosition); projectile.node.active = true; projectile.ContactBeginEvent.on(this.onProjectileCollision, this); @@ -129,8 +96,8 @@ export class ProjectileLauncher extends Component implements IProjectileCollisio private moveAllProjectiles(deltaTime: number): void { for (let i = 0; i < this.projectiles.length; i++) { const newPosition: Vec3 = this.projectiles[i].node.worldPosition; - newPosition.x += this.directions[i].x * deltaTime * this.speed; - newPosition.y += this.directions[i].y * deltaTime * this.speed; + newPosition.x += this.directions[i].x * deltaTime * this.projectileSpeed; + newPosition.y += this.directions[i].y * deltaTime * this.projectileSpeed; this.projectiles[i].node.setWorldPosition(newPosition); } diff --git a/assets/Scripts/Game/Unit/Player/ProjectileLauncher/WaveProjectileLauncher.ts b/assets/Scripts/Game/Unit/Player/ProjectileLauncher/WaveProjectileLauncher.ts index 7184899..1c8288d 100644 --- a/assets/Scripts/Game/Unit/Player/ProjectileLauncher/WaveProjectileLauncher.ts +++ b/assets/Scripts/Game/Unit/Player/ProjectileLauncher/WaveProjectileLauncher.ts @@ -1,5 +1,7 @@ import { Node, Vec2 } from "cc"; import { ISignal } from "../../../../Services/EventSystem/ISignal"; +import { GameTimer } from "../../../../Services/GameTimer"; +import { delay } from "../../../../Services/Utils/AsyncUtils"; import { WaveLauncherSettings } from "../../../Data/GameSettings"; import { IProjectileCollisionSignaler } from "../../../Projectile/IProjectileCollisionSignaler"; import { ProjectileCollision } from "../../../Projectile/ProjectileCollision"; @@ -8,6 +10,9 @@ import { ProjectileData, ProjectileLauncher } from "./ProjectileLauncher"; export class WaveProjectileLauncher implements IProjectileCollisionSignaler { private currentUpgrade = 0; private wavesToShootPerUpgrade = 0; + private fireTimer: GameTimer; + private wavesToShoot: number; + private wavesDelayMs: number; public constructor( private launcher: ProjectileLauncher, @@ -17,7 +22,12 @@ export class WaveProjectileLauncher implements IProjectileCollisionSignaler { projectileData: ProjectileData ) { this.wavesToShootPerUpgrade = settings.wavesToShootPerUpgrade; - launcher.init(settings.launcher, projectileData); + + this.fireTimer = new GameTimer(settings.launcher.cooldown); + this.wavesToShoot = settings.launcher.wavesToShoot; + this.wavesDelayMs = settings.launcher.wavesDelayMs; + + launcher.init(settings.launcher.projectileLifetime, settings.launcher.projectileSpeed, projectileData.damage, projectileData.pierces); } public get ProjectileCollisionEvent(): ISignal { @@ -27,11 +37,24 @@ export class WaveProjectileLauncher implements IProjectileCollisionSignaler { public gameTick(deltaTime: number): void { if (this.currentUpgrade == 0) return; - this.launcher.gameTick(deltaTime, this.playerNode.worldPosition, this.directions); + this.launcher.gameTick(deltaTime); + this.fireTimer.gameTick(deltaTime); + + if (this.fireTimer.tryFinishPeriod()) { + this.fireProjectiles(); + } } public upgrade(): void { this.currentUpgrade++; - this.launcher.WavesToShoot += this.wavesToShootPerUpgrade; + this.wavesToShoot += this.wavesToShootPerUpgrade; + } + + private async fireProjectiles(): Promise { + for (let i = 0; i < this.wavesToShoot; i++) { + this.launcher.fireProjectiles(this.playerNode.worldPosition, this.directions); + + await delay(this.wavesDelayMs); + } } }