From 2077c2e1c8669d92c154318ce8abf4fd60e6aca5 Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 12 Dec 2022 12:04:31 +0100 Subject: [PATCH] Movement improvements --- assets/Scripts/Game/Data/GameSettings.ts | 1 + assets/Scripts/Game/Game.ts | 3 +- .../Scripts/Game/Unit/Enemy/EnemyManager.ts | 16 +++--- .../Game/Unit/Enemy/EnemyMovementType.ts | 5 +- .../PeriodicFollowTargetEnemyMover.ts | 57 +++++++++++++++++++ .../PeriodicFollowTargetEnemyMover.ts.meta | 9 +++ .../EnemySpawner/CircularEnemySpawner.ts | 9 ++- .../EnemySpawner/IndividualEnemySpawner.ts | 4 +- .../Enemy/EnemySpawner/WaveEnemySpawner.ts | 2 + 9 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollowTargetEnemyMover.ts create mode 100644 assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollowTargetEnemyMover.ts.meta diff --git a/assets/Scripts/Game/Data/GameSettings.ts b/assets/Scripts/Game/Data/GameSettings.ts index 8c08b5b..b2bbb5d 100644 --- a/assets/Scripts/Game/Data/GameSettings.ts +++ b/assets/Scripts/Game/Data/GameSettings.ts @@ -56,5 +56,6 @@ export class WaveEnemySpawnerSettings { public cooldown = 0; public enemiesPerWave = 0; public waveLifetime = 0; + public moveType = ""; public enemyType = ""; } diff --git a/assets/Scripts/Game/Game.ts b/assets/Scripts/Game/Game.ts index 0c76e86..e1851f0 100644 --- a/assets/Scripts/Game/Game.ts +++ b/assets/Scripts/Game/Game.ts @@ -94,7 +94,8 @@ export class Game extends Component { this.gameUI.init(this.player); this.gamePauser.resume(); - await delay(10000); + // while not dead + await delay(100000); this.gamePauser.pause(); Game.instance = null; return 1; diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts b/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts index af35d23..8f3c77b 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemyManager.ts @@ -5,6 +5,7 @@ import { Enemy } from "./Enemy"; import { EnemyMovementType } from "./EnemyMovementType"; import { EnemyMover } from "./EnemyMover/EnemyMover"; import { FollowTargetEnemyMover } from "./EnemyMover/FollowTargetEnemyMover"; +import { PeriodicFollowTargetEnemyMover } from "./EnemyMover/PeriodicFollowTargetEnemyMover"; import { WaveEnemyMover } from "./EnemyMover/WaveEnemyMover"; import { CircularEnemySpawner } from "./EnemySpawner/CircularEnemySpawner"; import { EnemySpawner } from "./EnemySpawner/EnemySpawner"; @@ -30,12 +31,13 @@ export class EnemyManager extends Component { 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, 30, EnemyType.Basic); + this.individualEnemySpawner = new IndividualEnemySpawner(this.enemySpawner, EnemyMovementType.Follow, EnemyType.Basic); + this.circularEnemySpawner = new CircularEnemySpawner(this.enemySpawner, 30, EnemyMovementType.Follow, EnemyType.Basic); this.waveEnemySpawner = new WaveEnemySpawner(this.enemySpawner, settings.waveEnemySpawner); this.movementTypeToMover.set(EnemyMovementType.Follow, new FollowTargetEnemyMover(targetNode)); this.movementTypeToMover.set(EnemyMovementType.Launch, new WaveEnemyMover(targetNode)); + this.movementTypeToMover.set(EnemyMovementType.PeriodicFollow, new PeriodicFollowTargetEnemyMover(targetNode, 5, 5)); this.xpSpawner.init(); } @@ -50,16 +52,16 @@ export class EnemyManager extends Component { } } - private onEnemyAdded(enemy: Enemy): void { - enemy.DeathEvent.on(this.onEnemyDied, this); - this.getEnemyMover(enemy).addEnemy(enemy); - } - private onEnemyDied(enemy: Enemy): void { enemy.DeathEvent.off(this.onEnemyDied); this.xpSpawner.spawnXp(enemy.node.worldPosition, 1); } + private onEnemyAdded(enemy: Enemy): void { + enemy.DeathEvent.on(this.onEnemyDied, this); + this.getEnemyMover(enemy).addEnemy(enemy); + } + private onRemoveEnemy(enemy: Enemy): void { this.getEnemyMover(enemy).removeEnemy(enemy); } diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyMovementType.ts b/assets/Scripts/Game/Unit/Enemy/EnemyMovementType.ts index e1e244b..4d2a5c0 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemyMovementType.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemyMovementType.ts @@ -1,4 +1,5 @@ export enum EnemyMovementType { - Follow, - Launch + Follow = "Follow", + PeriodicFollow = "PeriodicFollow", + Launch = "Launch" } diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollowTargetEnemyMover.ts b/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollowTargetEnemyMover.ts new file mode 100644 index 0000000..4222833 --- /dev/null +++ b/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollowTargetEnemyMover.ts @@ -0,0 +1,57 @@ +import { Node, Vec3 } from "cc"; +import { Enemy } from "../Enemy"; +import { EnemyMover } from "./EnemyMover"; + +export class PeriodicFollowTargetEnemyMover extends EnemyMover { + private enemyToFollowState: Map = new Map(); + private enemyToStateTimeLeft: Map = new Map(); + + public constructor(targetNode: Node, private followTime: number, private waitTime: number) { + super(targetNode); + } + + public addEnemy(enemy: Enemy): void { + this.setEnemyFollowState(enemy, EnemyFollowState.Follow, this.followTime); + super.addEnemy(enemy); + } + + public removeEnemy(enemy: Enemy): void { + super.removeEnemy(enemy); + } + + public gameTick(deltaTime: number): void { + for (const enemy of this.enemies) { + const stateTimeLeft: number = this.enemyToStateTimeLeft.get(enemy) - deltaTime; + if (stateTimeLeft <= 0) { + this.switchEnemyFollowState(enemy); + } else { + this.enemyToStateTimeLeft.set(enemy, stateTimeLeft); + + if (this.enemyToFollowState.get(enemy) === EnemyFollowState.Follow) { + let direction: Vec3 = new Vec3(); + direction = Vec3.subtract(direction, this.targetNode.worldPosition, enemy.node.worldPosition); + enemy.moveBy(direction.normalize(), deltaTime); + } + } + } + } + + private switchEnemyFollowState(enemy: Enemy): void { + const followState: EnemyFollowState = this.enemyToFollowState.get(enemy); + if (followState === EnemyFollowState.Follow) { + this.setEnemyFollowState(enemy, EnemyFollowState.Wait, this.waitTime); + } else if (followState === EnemyFollowState.Wait) { + this.setEnemyFollowState(enemy, EnemyFollowState.Follow, this.followTime); + } + } + + private setEnemyFollowState(enemy: Enemy, followState: EnemyFollowState, stateTimeLeft: number): void { + this.enemyToFollowState.set(enemy, followState); + this.enemyToStateTimeLeft.set(enemy, stateTimeLeft); + } +} + +export enum EnemyFollowState { + Follow, + Wait +} diff --git a/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollowTargetEnemyMover.ts.meta b/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollowTargetEnemyMover.ts.meta new file mode 100644 index 0000000..88bd0a9 --- /dev/null +++ b/assets/Scripts/Game/Unit/Enemy/EnemyMover/PeriodicFollowTargetEnemyMover.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.23", + "importer": "typescript", + "imported": true, + "uuid": "02c4b3ec-3f77-485d-a539-32564ed5d63b", + "files": [], + "subMetas": {}, + "userData": {} +} diff --git a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/CircularEnemySpawner.ts b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/CircularEnemySpawner.ts index 53733d1..aacf25d 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/CircularEnemySpawner.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/CircularEnemySpawner.ts @@ -6,7 +6,12 @@ import { EnemySpawner } from "./EnemySpawner"; export class CircularEnemySpawner { private spawnTimer: GameTimer = new GameTimer(10); - public constructor(private enemySpawner: EnemySpawner, private enemiesToSpawn: number, private enemyType: EnemyType) {} + public constructor( + private enemySpawner: EnemySpawner, + private enemiesToSpawn: number, + private movementType: EnemyMovementType, + private enemyType: EnemyType + ) {} public gameTick(deltaTime: number): void { this.spawnTimer.gameTick(deltaTime); @@ -16,7 +21,7 @@ export class CircularEnemySpawner { 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, EnemyMovementType.Follow); + this.enemySpawner.spawnNewEnemy(posX, posY, this.movementType); } } } diff --git a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/IndividualEnemySpawner.ts b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/IndividualEnemySpawner.ts index 5a467d4..f9daa53 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/IndividualEnemySpawner.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/IndividualEnemySpawner.ts @@ -8,14 +8,14 @@ import { EnemySpawner } from "./EnemySpawner"; export class IndividualEnemySpawner { private spawnTimer: GameTimer = new GameTimer(1); - public constructor(private enemySpawner: EnemySpawner, private enemyType: EnemyType) {} + public constructor(private enemySpawner: EnemySpawner, private movementType: EnemyMovementType, private 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, EnemyMovementType.Follow); + this.enemySpawner.spawnNewEnemy(posX, posY, this.movementType); } } } diff --git a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/WaveEnemySpawner.ts b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/WaveEnemySpawner.ts index 6b33b50..b74bd4a 100644 --- a/assets/Scripts/Game/Unit/Enemy/EnemySpawner/WaveEnemySpawner.ts +++ b/assets/Scripts/Game/Unit/Enemy/EnemySpawner/WaveEnemySpawner.ts @@ -10,6 +10,7 @@ import { EnemySpawner } from "./EnemySpawner"; export class WaveEnemySpawner { private enemiesPerWave: number; private waveLifetime: number; + private moveType: EnemyMovementType; private enemyType: EnemyType; private spawnTimer: GameTimer; @@ -19,6 +20,7 @@ export class WaveEnemySpawner { this.spawnTimer = new GameTimer(settings.cooldown); this.enemiesPerWave = settings.enemiesPerWave; this.waveLifetime = settings.waveLifetime; + this.moveType = settings.moveType; this.enemyType = settings.enemyType; }