From 7f27f3aef79914df1a26ae0b59f19c4d5e7003f8 Mon Sep 17 00:00:00 2001 From: koneko <67551503+koneko@users.noreply.github.com> Date: Fri, 7 Feb 2025 19:51:51 +0100 Subject: [PATCH] working --- index.html | 3 +- public/assets/missions/04_crossroads.json | 164 ++++++------ public/assets/missions/05_the_maze.json | 235 +++++++++++------- .../assets/missions/06_multiple_fronts.json | 160 +++++------- public/assets/missions/07_final_stretch.json | 223 +++++++++++++++++ public/favicon.ico | Bin 0 -> 16958 bytes public/favicon.png | Bin 0 -> 9841 bytes src/classes/Assets.ts | 1 + src/classes/Bastion.ts | 1 + src/classes/game/Gem.ts | 7 +- src/classes/game/Grid.ts | 19 +- src/classes/game/NotificationManager.ts | 4 +- src/classes/game/WaveManager.ts | 15 +- src/main.ts | 2 +- src/scenes/Game.ts | 5 + src/scenes/Scene.ts | 1 + 16 files changed, 555 insertions(+), 285 deletions(-) create mode 100644 public/assets/missions/07_final_stretch.json create mode 100644 public/favicon.ico create mode 100644 public/favicon.png diff --git a/index.html b/index.html index 707302d..4528b2a 100644 --- a/index.html +++ b/index.html @@ -2,11 +2,10 @@ - - Bastion App + Bastion: The Watcher's Lament diff --git a/public/assets/missions/04_crossroads.json b/public/assets/missions/04_crossroads.json index 75f356f..8ec1145 100644 --- a/public/assets/missions/04_crossroads.json +++ b/public/assets/missions/04_crossroads.json @@ -28,101 +28,79 @@ ], "paths": [ [ - [0, 4], - [1, 4], - [2, 4], - [3, 4], - [4, 4], - [5, 4], - [6, 4], - [7, 4], - [8, 4], - [9, 4], - [10, 4], - [11, 4], - [12, 4], - [13, 4], - [14, 4], - [15, 4], - [16, 4], - [16, 5], - [16, 6], - [16, 7], - [16, 8], - [16, 9], - [16, 10], - [16, 11], - [16, 12], - [16, 13], - [16, 14], - [16, 15], - [16, 16], - [16, 17], - [16, 18], - [16, 19], - [16, 20], - [16, 21], - [16, 22], - [16, 23], - [16, 24] - ], - [ - [4, 0], - [4, 1], - [4, 2], - [4, 3], - [4, 4], - [4, 5], - [4, 6], - [4, 7], - [4, 8], - [4, 9], - [4, 10], - [4, 11], - [4, 12], + [0, 13], + [1, 13], + [2, 13], + [3, 13], [4, 13], - [4, 14], - [4, 15], - [4, 16], - [4, 17], - [4, 18], - [4, 19], - [4, 20], - [4, 21], - [4, 22], - [4, 23], - [4, 24] + [5, 13], + [6, 13], + [7, 13], + [8, 13], + [9, 13], + [10, 13], + [11, 13], + [12, 13], + [13, 13], + [14, 13], + [15, 13], + [15, 12], + [15, 11], + [15, 10], + [16, 10], + [17, 10], + [18, 10], + [19, 10], + [20, 10], + [20, 9], + [20, 8], + [20, 7], + [20, 6], + [21, 6], + [22, 6], + [23, 6], + [24, 6] ], [ - [0, 12], - [1, 12], - [2, 12], - [3, 12], - [4, 12], - [5, 12], - [6, 12], - [7, 12], - [8, 12], - [9, 12], - [10, 12], - [11, 12], - [12, 12], - [13, 12], - [14, 12], - [15, 12], - [16, 12], - [16, 13], - [16, 14], - [16, 15], - [16, 16], - [16, 17], - [16, 18], - [16, 19], - [16, 20], - [16, 21], - [16, 22], - [16, 23], - [16, 24] + [14, 0], + [14, 1], + [14, 2], + [13, 2], + [12, 2], + [11, 2], + [10, 2], + [9, 2], + [8, 2], + [7, 2], + [7, 3], + [7, 4], + [7, 5], + [8, 5], + [9, 5], + [10, 5], + [11, 5], + [12, 5], + [12, 6], + [12, 7], + [12, 8], + [12, 9], + [12, 10], + [13, 10], + [14, 10], + [15, 10], + [16, 10], + [17, 10], + [18, 10], + [19, 10], + [20, 10], + [20, 9], + [20, 8], + [20, 7], + [20, 6], + [21, 6], + [22, 6], + [23, 6], + [24, 6] ] ] }, @@ -140,7 +118,7 @@ "creeps": [1, 1, 2, 1, 1] } ], - "offeredGems": [0, 1, 2] + "offeredGems": [0, 1, 2, 0] }, { "waves": [ diff --git a/public/assets/missions/05_the_maze.json b/public/assets/missions/05_the_maze.json index 7db8bb5..45e1ce9 100644 --- a/public/assets/missions/05_the_maze.json +++ b/public/assets/missions/05_the_maze.json @@ -28,97 +28,158 @@ ], "paths": [ [ - [0, 3], - [1, 3], - [2, 3], - [3, 3], - [4, 3], - [4, 4], - [4, 5], - [4, 6], - [4, 7], - [4, 8], - [4, 9], - [4, 10], - [4, 11], - [4, 12], - [5, 12], - [6, 12], - [7, 12], - [8, 12], - [8, 13], - [8, 14], - [8, 15], - [8, 16], - [8, 17], - [8, 18], - [8, 19], - [8, 20], - [8, 21], - [8, 22], - [8, 23], - [8, 24] - ], - [ - [0, 8], - [1, 8], - [2, 8], - [3, 8], - [4, 8], - [5, 8], - [6, 8], - [7, 8], - [8, 8], - [9, 8], - [10, 8], - [11, 8], - [12, 8], - [12, 9], - [12, 10], - [12, 11], - [12, 12], - [12, 13], + [0, 1], + [1, 1], + [2, 1], + [3, 1], + [4, 1], + [5, 1], + [6, 1], + [7, 1], + [8, 1], + [9, 1], + [10, 1], + [11, 1], + [12, 1], + [13, 1], + [14, 1], + [15, 1], + [16, 1], + [17, 1], + [17, 2], + [17, 3], + [17, 4], + [17, 5], + [17, 6], + [17, 7], + [17, 8], + [17, 9], + [17, 10], + [17, 11], + [17, 12], + [17, 13], + [17, 14], + [16, 14], + [15, 14], + [14, 14], + [13, 14], [12, 14], - [12, 15], - [12, 16], - [12, 17], - [12, 18], - [12, 19], - [12, 20], - [12, 21], - [12, 22], - [12, 23], - [12, 24] + [11, 14], + [10, 14], + [9, 14], + [8, 14], + [7, 14], + [6, 14], + [5, 14], + [5, 13], + [5, 12], + [5, 11], + [5, 10], + [5, 9], + [6, 9], + [7, 9], + [8, 9], + [9, 9], + [10, 9], + [10, 10], + [10, 11], + [11, 11], + [12, 11], + [13, 11], + [14, 11], + [14, 10], + [14, 9], + [14, 8], + [14, 7], + [15, 7], + [16, 7], + [17, 7], + [18, 7], + [19, 7], + [20, 7], + [21, 7], + [22, 7], + [22, 8], + [23, 8], + [24, 8] ], [ - [0, 13], - [1, 13], + [0, 15], + [1, 15], + [2, 15], + [2, 14], [2, 13], - [3, 13], - [4, 13], - [4, 14], - [4, 15], - [4, 16], - [4, 17], - [4, 18], - [4, 19], - [4, 20], - [5, 20], - [6, 20], - [7, 20], - [8, 20], - [9, 20], - [10, 20], - [11, 20], - [12, 20], - [13, 20], - [14, 20], - [15, 20], - [16, 20], - [16, 21], - [16, 22], - [16, 23], - [16, 24] + [2, 12], + [2, 11], + [2, 10], + [2, 9], + [2, 8], + [2, 7], + [2, 6], + [2, 5], + [2, 4], + [3, 4], + [4, 4], + [5, 4], + [6, 4], + [7, 4], + [8, 4], + [9, 4], + [10, 4], + [11, 4], + [12, 4], + [13, 4], + [14, 4], + [14, 5], + [14, 6], + [14, 7], + [14, 8], + [14, 9], + [14, 10], + [14, 11], + [13, 11], + [12, 11], + [11, 11], + [10, 11], + [10, 10], + [10, 9], + [9, 9], + [8, 9], + [7, 9], + [6, 9], + [5, 9], + [5, 10], + [5, 11], + [5, 12], + [5, 13], + [5, 14], + [6, 14], + [7, 14], + [8, 14], + [9, 14], + [10, 14], + [11, 14], + [12, 14], + [13, 14], + [14, 14], + [15, 14], + [16, 14], + [17, 14], + [17, 13], + [17, 12], + [17, 11], + [17, 10], + [17, 9], + [17, 8], + [17, 7], + [18, 7], + [19, 7], + [20, 7], + [21, 7], + [22, 7], + [22, 8], + [23, 8], + [24, 8] ] ] }, diff --git a/public/assets/missions/06_multiple_fronts.json b/public/assets/missions/06_multiple_fronts.json index 2de19b2..24d7d3e 100644 --- a/public/assets/missions/06_multiple_fronts.json +++ b/public/assets/missions/06_multiple_fronts.json @@ -28,101 +28,79 @@ ], "paths": [ [ - [8, 0], - [8, 1], - [8, 2], - [8, 3], - [8, 4], + [5, 0], + [5, 1], + [5, 2], + [4, 2], + [3, 2], + [2, 2], + [2, 3], + [2, 4], + [2, 5], + [3, 5], + [4, 5], + [5, 5], + [6, 5], + [7, 5], [8, 5], - [8, 6], - [8, 7], - [8, 8], - [7, 8], - [6, 8], - [5, 8], - [4, 8], - [4, 9], - [4, 10], - [4, 11], - [4, 12], - [4, 13], - [4, 14], + [9, 5], + [10, 5], + [11, 5], + [12, 5], + [13, 5], + [13, 4], + [13, 3], + [13, 2], + [14, 2], + [15, 2], + [16, 2], + [17, 2], + [18, 2], + [19, 2], + [20, 2], + [21, 2], + [21, 3], + [21, 4], + [21, 5], + [22, 5], + [23, 5], + [24, 5] + ], + [ + [0, 9], + [1, 9], + [2, 9], + [2, 10], + [2, 11], + [2, 12], + [2, 13], + [2, 14], + [2, 15], + [3, 15], [4, 15], - [4, 16], - [4, 17], - [4, 18], - [4, 19], - [4, 20], - [4, 21], - [4, 22], - [4, 23], - [4, 24] - ], - [ - [8, 0], - [8, 1], - [8, 2], - [8, 3], - [8, 4], - [8, 5], - [8, 6], - [8, 7], - [8, 8], - [9, 8], - [10, 8], - [11, 8], - [12, 8], - [12, 9], - [12, 10], - [12, 11], - [12, 12], + [5, 15], + [6, 15], + [7, 15], + [8, 15], + [9, 15], + [10, 15], + [11, 15], + [11, 14], + [11, 13], [12, 13], - [12, 14], - [12, 15], - [12, 16], - [12, 17], - [12, 18], - [12, 19], - [12, 20], - [12, 21], - [12, 22], - [12, 23], - [12, 24] - ], - [ - [0, 8], - [1, 8], - [2, 8], - [3, 8], - [4, 8], - [5, 8], - [6, 8], - [7, 8], - [8, 8], - [9, 8], - [10, 8], - [11, 8], - [12, 8], - [13, 8], - [14, 8], - [15, 8], - [16, 8], - [16, 9], - [16, 10], - [16, 11], - [16, 12], + [13, 13], + [14, 13], + [15, 13], [16, 13], - [16, 14], - [16, 15], - [16, 16], - [16, 17], - [16, 18], - [16, 19], - [16, 20], - [16, 21], - [16, 22], - [16, 23], - [16, 24] + [17, 13], + [17, 14], + [18, 14], + [19, 14], + [20, 14], + [21, 14], + [22, 14], + [23, 14], + [24, 14] ] ] }, diff --git a/public/assets/missions/07_final_stretch.json b/public/assets/missions/07_final_stretch.json new file mode 100644 index 0000000..3ad9349 --- /dev/null +++ b/public/assets/missions/07_final_stretch.json @@ -0,0 +1,223 @@ +{ + "name": "Final Stretch", + "description": "The final map, the longest map, the 7th map.", + "mapImage": { + "url": "/assets/maps/07_final_stretch.png" + }, + "gameMap": { + "rows": 17, + "columns": 25, + "cells": [ + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + ], + "paths": [ + [ + [2, 0], + [2, 1], + [2, 2], + [2, 3], + [2, 4], + [2, 5], + [2, 6], + [2, 7], + [2, 8], + [2, 9], + [2, 10], + [2, 11], + [2, 12], + [2, 13], + [2, 14], + [3, 14], + [4, 14], + [5, 14], + [6, 14], + [6, 13], + [6, 12], + [6, 11], + [6, 10], + [6, 9], + [6, 8], + [6, 7], + [6, 6], + [6, 5], + [6, 4], + [6, 3], + [6, 2], + [7, 2], + [8, 2], + [9, 2], + [10, 2], + [10, 3], + [10, 4], + [10, 5], + [10, 6], + [10, 7], + [10, 8], + [10, 9], + [10, 10], + [10, 11], + [10, 12], + [10, 13], + [10, 14], + [11, 14], + [12, 14], + [13, 14], + [14, 14], + [14, 13], + [14, 12], + [14, 11], + [14, 10], + [14, 9], + [14, 8], + [14, 7], + [14, 6], + [14, 5], + [14, 4], + [14, 3], + [14, 2], + [15, 2], + [16, 2], + [17, 2], + [18, 2], + [18, 3], + [18, 4], + [18, 5], + [18, 6], + [18, 7], + [18, 8], + [18, 9], + [18, 10], + [18, 11], + [18, 12], + [18, 13], + [18, 14], + [19, 14], + [20, 14], + [21, 14], + [22, 14], + [22, 13], + [22, 12], + [22, 11], + [22, 10], + [22, 9], + [22, 8], + [22, 7], + [22, 6], + [22, 5], + [22, 4], + [22, 3], + [22, 2], + [22, 1], + [22, 0] + ] + ] + }, + "rounds": [ + { + "waves": [ + { + "firstCreepSpawnTick": 500, + "spawnIntervalTicks": 700, + "creeps": [0, 1, 0, 1, 0, 1, 0] + }, + { + "firstCreepSpawnTick": 5000, + "spawnIntervalTicks": 500, + "creeps": [1, 1, 2, 1, 1, 2, 1] + } + ], + "offeredGems": [0, 1, 2, 3] + }, + { + "waves": [ + { + "firstCreepSpawnTick": 500, + "spawnIntervalTicks": 600, + "creeps": [2, 1, 2, 1, 2, 1, 2, 1] + }, + { + "firstCreepSpawnTick": 6000, + "spawnIntervalTicks": 400, + "creeps": [2, 2, 1, 1, 2, 2, 1, 1] + } + ], + "offeredGems": [0, 1, 2, 3] + }, + { + "waves": [ + { + "firstCreepSpawnTick": 500, + "spawnIntervalTicks": 500, + "creeps": [2, 2, 1, 1, 2, 2, 1, 1, 2] + }, + { + "firstCreepSpawnTick": 6000, + "spawnIntervalTicks": 300, + "creeps": [2, 2, 2, 1, 1, 1, 2, 2, 2] + } + ], + "offeredGems": [0, 1, 2, 3] + }, + { + "waves": [ + { + "firstCreepSpawnTick": 500, + "spawnIntervalTicks": 400, + "creeps": [2, 2, 2, 1, 1, 1, 2, 2, 2, 1] + }, + { + "firstCreepSpawnTick": 7000, + "spawnIntervalTicks": 250, + "creeps": [2, 2, 2, 2, 1, 1, 1, 1, 2, 2] + } + ], + "offeredGems": [0, 1, 2, 3] + }, + { + "waves": [ + { + "firstCreepSpawnTick": 500, + "spawnIntervalTicks": 300, + "creeps": [2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2] + }, + { + "firstCreepSpawnTick": 7000, + "spawnIntervalTicks": 200, + "creeps": [2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2] + } + ], + "offeredGems": [0, 1, 2, 3] + }, + { + "waves": [ + { + "firstCreepSpawnTick": 500, + "spawnIntervalTicks": 250, + "creeps": [2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2] + }, + { + "firstCreepSpawnTick": 8000, + "spawnIntervalTicks": 150, + "creeps": [2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1] + } + ], + "offeredGems": [0, 1, 2, 3] + } + ] +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c4cfea946a64fe02ac272ad35085c26e72607585 GIT binary patch literal 16958 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 literal 0 HcmV?d00001 diff --git a/src/classes/Assets.ts b/src/classes/Assets.ts index c25519b..33ada65 100644 --- a/src/classes/Assets.ts +++ b/src/classes/Assets.ts @@ -158,6 +158,7 @@ export default class GameAssets { await this.LoadMission('./assets/missions/04_crossroads.json'); await this.LoadMission('./assets/missions/05_the_maze.json'); await this.LoadMission('./assets/missions/06_multiple_fronts.json'); + await this.LoadMission('./assets/missions/07_final_stretch.json'); } private static async LoadTowers() { diff --git a/src/classes/Bastion.ts b/src/classes/Bastion.ts index b8fc872..179cf49 100644 --- a/src/classes/Bastion.ts +++ b/src/classes/Bastion.ts @@ -22,6 +22,7 @@ export class Engine { public static NotificationManager: NotificationManager; public static GameScene: GameScene; public static latestCommit: string; + public static latestGemId = 0; public static GridCellSize: number = 64; public static GridColumns: number = 25; diff --git a/src/classes/game/Gem.ts b/src/classes/game/Gem.ts index b699dbc..8f0bc07 100644 --- a/src/classes/game/Gem.ts +++ b/src/classes/game/Gem.ts @@ -1,8 +1,7 @@ import * as PIXI from 'pixi.js'; import { GemType, GemDefinition, GenericGemImprovement } from '../Definitions'; import GameAssets from '../Assets'; - -let latestGemId = 0; +import { Engine } from '../Bastion'; export default class Gem { public texture: PIXI.Texture; @@ -14,8 +13,8 @@ export default class Gem { this.texture = this.definition.textures[0]; if (!doNotIncrement) { - this.id = latestGemId + 1; - latestGemId++; + this.id = Engine.latestGemId + 1; + Engine.latestGemId++; } else this.id = ''; } public currentGemImprovement() { diff --git a/src/classes/game/Grid.ts b/src/classes/game/Grid.ts index dd3c1a4..3416bb0 100644 --- a/src/classes/game/Grid.ts +++ b/src/classes/game/Grid.ts @@ -6,6 +6,8 @@ import { Engine } from '../Bastion'; import Creep from './Creep'; import { CreepEvents, TowerEvents, GridEvents } from '../Events'; +let genPath = []; + export class Cell extends GameObject { public type: TerrainType; public row: number; @@ -55,6 +57,7 @@ export class Cell extends GameObject { Engine.GameScene.events.emit(GridEvents.CellMouseLeave, this); Engine.Grid.rangePreview.clear(); }); + Engine.GameScene.events.on(TowerEvents.TowerPlacedEvent, (_, row, col) => { if (row == this.row && col == this.column) { this.hasTowerPlaced = true; @@ -68,11 +71,13 @@ export class Cell extends GameObject { }); // Disable this if you want to add new maps. - // if(true) return; + if (true) return; + const text = new PIXI.Text({ text: `${this.column}|${this.row}`, style: new PIXI.TextStyle({ fill: 0xffffff, + fontSize: 16, stroke: { color: 0x000000, width: 2, @@ -87,6 +92,18 @@ export class Cell extends GameObject { text.style.fill = 'pink'; text.style.fontWeight = 'bold'; } + this.clickDetector.on('pointerup', () => { + const cellIndex = genPath.findIndex(([col, row]) => col === this.column && row === this.row); + if (cellIndex !== -1) { + text.style.fill = 0xffffff; + genPath.splice(cellIndex, 1); + } else { + text.style.fill = 0xff0000; + genPath.push([this.column, this.row]); + } + console.log('updated gen path'); + console.log(JSON.stringify(genPath)); + }); } public showRangePreview(invalid, range) { let color = 0xffffff; diff --git a/src/classes/game/NotificationManager.ts b/src/classes/game/NotificationManager.ts index 737be4e..547155b 100644 --- a/src/classes/game/NotificationManager.ts +++ b/src/classes/game/NotificationManager.ts @@ -3,7 +3,7 @@ import GameObject from '../GameObject'; import * as PIXI from 'pixi.js'; import { FadeInOut } from './AnimationManager'; -export type NotificationType = 'info' | 'warn' | 'danger' | 'reward' | 'gemaward'; +export type NotificationType = 'info' | 'warn' | 'danger' | 'reward' | 'gemaward' | 'green'; class Notification { public textObj: PIXI.Text; @@ -22,6 +22,8 @@ class Notification { fill = 0xd65afc; } else if (type == 'gemaward') { fill = 0xffffff; + } else if (type == 'green') { + fill = 0x00ff00; } this.ticksToFadeAway = ticksToFadeAway; this.textObj = new PIXI.Text({ diff --git a/src/classes/game/WaveManager.ts b/src/classes/game/WaveManager.ts index 0adbf9d..4c73a1e 100644 --- a/src/classes/game/WaveManager.ts +++ b/src/classes/game/WaveManager.ts @@ -17,31 +17,38 @@ export default class WaveManager extends GameObject { private paths: PathDefinition[]; private ticks: number = 0; private started: boolean = false; - public finished: boolean = false; private internalCreepId: number = 0; + private pathsIndex: number; + public finished: boolean = false; + constructor(rounds: MissionRoundDefinition[], paths: PathDefinition[]) { super(); Engine.WaveManager = this; this.rounds = rounds; this.paths = paths; + this.pathsIndex = 0; } public start(roundIndex) { this.started = true; this.ticks = 0; this.creeps = []; this.finished = false; + if (this.pathsIndex + 1 == this.paths.length) { + this.pathsIndex = 0; + } else { + this.pathsIndex++; + } let tickToSpawnAt = 0; this.rounds[roundIndex].waves.forEach((wave) => { tickToSpawnAt += wave.firstCreepSpawnTick; wave.creeps.forEach((creep) => { - const creepObj = new Creep(creep, this.paths[0], this.internalCreepId); + const creepObj = new Creep(creep, this.paths[this.pathsIndex], this.internalCreepId); this.internalCreepId++; const creepInstance = { creep: creepObj, tickToSpawnAt, spawned: false, }; - console.log('CREAWTASEDASD'); tickToSpawnAt += wave.spawnIntervalTicks; this.creeps.push(creepInstance); }); @@ -58,10 +65,8 @@ export default class WaveManager extends GameObject { if (!creep.spawned && creep.tickToSpawnAt <= this.ticks) { creep.spawned = true; this.events.emit(WaveManagerEvents.CreepSpawned, creep.creep); - console.log('Wave manager creep spawned, ', creep, this.ticks); if (!this.finished && this.creeps.every((creep) => creep.spawned)) { this.finished = true; - console.log('wave manager finished'); this.events.emit(WaveManagerEvents.Finished); } } else if (creep.spawned) { diff --git a/src/main.ts b/src/main.ts index dcb047e..6311fad 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,8 +6,8 @@ import { GameScene } from './scenes/Game'; import { AnimationManager } from './classes/game/AnimationManager'; import NotificationManager from './classes/game/NotificationManager'; import GameUIConstants from './classes/GameUIConstants'; -import MessageBox from './classes/gui/MessageBox'; import KeyboardManager from './classes/game/KeyboardManager'; +import { GemType } from './classes/Definitions'; (async () => { const app = new PIXI.Application(); diff --git a/src/scenes/Game.ts b/src/scenes/Game.ts index 3ad74e3..8ed5ebf 100644 --- a/src/scenes/Game.ts +++ b/src/scenes/Game.ts @@ -59,6 +59,7 @@ export class GameScene extends Scene { }); } public init() { + Engine.latestGemId = 0; new Grid(this.mission.gameMap, this.missionIndex); new TowerManager(); new WaveManager(this.mission.rounds, this.mission.gameMap.paths); @@ -257,10 +258,14 @@ export class GameScene extends Scene { this.ReturnToMain(); } else if (result === HighScoreDialogButtons.NextMission) { this.destroy(); + Engine.GameMaster.changeScene(new MissionPickerScene()); Engine.GameMaster.changeScene(new GameScene(GameAssets.Missions[this.missionIndex + 1].name)); + Engine.NotificationManager.Notify('Loading next mission. Good luck.', 'green'); } else if (result === HighScoreDialogButtons.Retry) { this.destroy(); + Engine.GameMaster.changeScene(new MissionPickerScene()); Engine.GameMaster.changeScene(new GameScene(this.mission.name)); + Engine.NotificationManager.Notify('Retrying mission.', 'green'); } } diff --git a/src/scenes/Scene.ts b/src/scenes/Scene.ts index 0e2d9d6..0686908 100644 --- a/src/scenes/Scene.ts +++ b/src/scenes/Scene.ts @@ -12,6 +12,7 @@ export default class Scene { } public destroy() { this.stage.destroy(); + this._events.removeAllListeners(); this.gui.forEach((element) => { element.destroy(); });