diff --git a/src/app/components/game/game.component.html b/src/app/components/game/game.component.html
index 90af569..c504b00 100644
--- a/src/app/components/game/game.component.html
+++ b/src/app/components/game/game.component.html
@@ -7,9 +7,9 @@
-
-
-
+
+
+
Step: {{ simMain.currentStep }}
diff --git a/src/app/components/game/game.component.ts b/src/app/components/game/game.component.ts
index 8e39565..39da3c1 100644
--- a/src/app/components/game/game.component.ts
+++ b/src/app/components/game/game.component.ts
@@ -44,19 +44,25 @@ export class GameComponent {
}
rewind() {
- if (this.simMain.currentLevel)
- this.simMain.currentLevel.currentStep = -1;
-
- this.simMain.currentStep = -1;
+ const wasActive = this.visMain.active;
+ if (wasActive)
+ this.visMain.stop();
+ this.simMain.rewind();
+ if (wasActive)
+ this.visMain.start();
}
startNextWave() {
this.simMain.addCommand(new SimCommandStartNextWave());
- this.simMain.currentLevel!.paused = false;
}
fastForward() {
+ const wasActive = this.visMain.active;
+ if (wasActive)
+ this.visMain.stop();
this.simMain.executeToEnd();
+ if (wasActive)
+ this.visMain.start();
}
async loadGdRoot(): Promise
{
diff --git a/src/app/components/game/sim/SimMain.ts b/src/app/components/game/sim/SimMain.ts
index f77cd24..a30b8fd 100644
--- a/src/app/components/game/sim/SimMain.ts
+++ b/src/app/components/game/sim/SimMain.ts
@@ -10,6 +10,7 @@ import { SimLevel } from './SimLevel';
export class SimMain {
currentStep = -1;
+ maxStep = -1;
currentLevel: SimLevel | null = null;
commandHistory: SimCommand[] = [];
gdRoot: GdRoot = null!;
@@ -30,9 +31,7 @@ export class SimMain {
}
executeToEnd() {
- this.executeUntilStep(
- this.commandHistory[this.commandHistory.length - 1].step
- );
+ this.executeUntilStep(this.maxStep);
}
executeUntilStep(target: number) {
@@ -41,8 +40,14 @@ export class SimMain {
}
}
+ rewind() {
+ this.currentLevel = new SimLevel(this.gdRoot, this.currentLevel?.index ?? 0);
+ this.currentStep = -1;
+ }
+
step() {
this.currentStep++;
+ this.maxStep = Math.max(this.maxStep, this.currentStep);
if (this.currentLevel && !this.currentLevel.paused) {
this.currentLevel.currentStep++;
}
diff --git a/src/app/components/game/sim/commands/SimCommandStartNextWave.ts b/src/app/components/game/sim/commands/SimCommandStartNextWave.ts
index cd2c87c..685818c 100644
--- a/src/app/components/game/sim/commands/SimCommandStartNextWave.ts
+++ b/src/app/components/game/sim/commands/SimCommandStartNextWave.ts
@@ -17,6 +17,7 @@ export class SimCommandStartNextWave extends SimCommand {
level.nextWaveStep = level.currentStep + simMain.gdRoot.simulation.waveDuration * simMain.gdRoot.simulation.stepsPerSecond - 1;
level.lastEnemySpawnStep = level.currentStep;
level.enemiesLeftToSpawn = data.waves[level.currentWave].amount;
+ level.paused = false;
}
public check(simMain: SimMain): boolean {
diff --git a/src/app/components/game/vis/VisLevel.ts b/src/app/components/game/vis/VisLevel.ts
index 2ca1313..2e5537b 100644
--- a/src/app/components/game/vis/VisLevel.ts
+++ b/src/app/components/game/vis/VisLevel.ts
@@ -1,312 +1,305 @@
-import { AssetPreloaderService } from "../../../assetPreloaderService";
-import { GdRoot } from "../data/GdRoot";
-import { ECellType } from "../sim/ECellType";
-import { SimCell } from "../sim/SimCell";
-import { SimEnemy } from "../sim/SimEnemy";
-import { SimLevel } from "../sim/SimLevel";
-import { SimMain } from "../sim/SimMain";
-import { SimProjectile } from "../sim/SimProjectile";
-import { Hex } from "../util/Hex";
-import { Vector2 } from "../util/Vector2";
-import { VisEnemy } from "./VisEnemy";
-import { VisMain } from "./VisMain";
-import { VisProjectile } from "./VisProjectile";
+import { AssetPreloaderService } from '../../../assetPreloaderService';
+import { GdRoot } from '../data/GdRoot';
+import { ECellType } from '../sim/ECellType';
+import { SimCell } from '../sim/SimCell';
+import { SimEnemy } from '../sim/SimEnemy';
+import { SimLevel } from '../sim/SimLevel';
+import { SimMain } from '../sim/SimMain';
+import { SimProjectile } from '../sim/SimProjectile';
+import { Hex } from '../util/Hex';
+import { Vector2 } from '../util/Vector2';
+import { VisEnemy } from './VisEnemy';
+import { VisMain } from './VisMain';
+import { VisProjectile } from './VisProjectile';
export class VisLevel {
- private screenCellWidth: number = -1;
- private screenCellHeight: number = -1;
- private screenXOffset: number = -1;
- private screenYOffset: number = -1;
- private hexSize: number = -1;
- private lastStep: number = -1;
- private projectileMap: Map;
- private enemyMap: Map;
- private background: HTMLCanvasElement | null = null;
- private simLevel: SimLevel | null = null;
- private visMain: VisMain;
- private simMain: SimMain;
- private gdRoot: GdRoot;
- assets: AssetPreloaderService;
- private hoveredHex: Hex | null = null;
+ private screenCellWidth: number = -1;
+ private screenCellHeight: number = -1;
+ private screenXOffset: number = -1;
+ private screenYOffset: number = -1;
+ private hexSize: number = -1;
+ private lastStep: number = -1;
+ private projectileMap: Map;
+ private enemyMap: Map;
+ private background: HTMLCanvasElement | null = null;
+ private simLevel: SimLevel | null = null;
+ private visMain: VisMain;
+ private simMain: SimMain;
+ private gdRoot: GdRoot;
+ assets: AssetPreloaderService;
+ private hoveredHex: Hex | null = null;
- constructor(visMain: VisMain, simMain: SimMain, gdRoot: GdRoot, assets: AssetPreloaderService) {
- this.assets = assets;
- this.visMain = visMain;
- this.simMain = simMain;
- this.gdRoot = gdRoot
- this.enemyMap = new Map();
- this.projectileMap = new Map();
- this.reset();
- }
+ constructor(visMain: VisMain, simMain: SimMain, gdRoot: GdRoot, assets: AssetPreloaderService) {
+ this.assets = assets;
+ this.visMain = visMain;
+ this.simMain = simMain;
+ this.gdRoot = gdRoot;
+ this.enemyMap = new Map();
+ this.projectileMap = new Map();
+ this.reset();
+ }
- public reset() {
- this.projectileMap.clear();
- this.enemyMap.clear();
- this.background = null;
- }
+ public reset() {
+ this.projectileMap.clear();
+ this.enemyMap.clear();
+ this.background = null;
+ }
- public draw() {
- const ctx = this.visMain.context;
- const simLevel = this.simMain.currentLevel;
- if (simLevel == null) {
- return;
- }
- const gdLevel = this.gdRoot.levels[simLevel.index];
+ public draw() {
+ const ctx = this.visMain.context;
+ const simLevel = this.simMain.currentLevel;
+ if (simLevel == null) {
+ return;
+ }
+ const gdLevel = this.gdRoot.levels[simLevel.index];
- if (simLevel != this.simLevel) {
- this.reset();
- this.simLevel = simLevel;
- }
+ if (simLevel != this.simLevel) {
+ this.reset();
+ this.simLevel = simLevel;
+ }
- this.drawBackground();
- ctx.globalCompositeOperation = "source-over";
+ this.drawBackground();
+ ctx.globalCompositeOperation = 'source-over';
- // Highlight hovered cell first (under everything else)
- if (this.hoveredHex) {
- const hoveredIdx = simLevel.getCellIndex(this.hoveredHex);
- const hoveredCell = simLevel.cells[hoveredIdx];
- if (hoveredCell && hoveredCell.distance <= gdLevel.radius) {
- this.drawCellImage(ctx, hoveredCell, "cell-highlighted.svg");
- }
- }
+ // Highlight hovered cell first (under everything else)
+ if (this.hoveredHex) {
+ const hoveredIdx = simLevel.getCellIndex(this.hoveredHex);
+ const hoveredCell = simLevel.cells[hoveredIdx];
+ if (hoveredCell && hoveredCell.distance <= gdLevel.radius) {
+ this.drawCellImage(ctx, hoveredCell, 'cell-highlighted.svg');
+ }
+ }
- simLevel.cells.forEach((cell: SimCell) => {
- if (cell.distance > gdLevel.radius) {
- return;
- }
- this.drawCell(cell);
- });
+ simLevel.cells.forEach((cell: SimCell) => {
+ if (cell.distance > gdLevel.radius) {
+ return;
+ }
+ this.drawCell(cell);
+ });
- simLevel.enemies.forEach((enemy: SimEnemy) => {
- this.drawEnemy(enemy);
- });
+ simLevel.enemies.forEach((enemy: SimEnemy) => {
+ this.drawEnemy(enemy);
+ });
- simLevel.projectiles.forEach((projectile: SimProjectile) => {
- this.drawProjectile(projectile);
- });
+ simLevel.projectiles.forEach((projectile: SimProjectile) => {
+ this.drawProjectile(projectile);
+ });
- ctx.fillStyle = "white";
- ctx.fillText("Currency: " + simLevel.currency, 5, 15);
- ctx.fillText("Current wave: " + simLevel.currentWave, 5, 35);
- ctx.fillText("Enemies left: " + simLevel.enemiesLeftToSpawn, 5, 55);
- ctx.fillText("Current step: " + simLevel.currentStep, 5, 75);
- }
+ ctx.fillStyle = 'white';
+ ctx.fillText('Currency: ' + simLevel.currency, 5, 15);
+ ctx.fillText('Current wave: ' + simLevel.currentWave, 5, 35);
+ ctx.fillText('Enemies left: ' + simLevel.enemiesLeftToSpawn, 5, 55);
+ ctx.fillText('Current step: ' + simLevel.currentStep, 5, 75);
+ }
- public updateSize() {
- const simLevel = this.simMain.currentLevel;
- if (simLevel == null) {
- return;
- }
+ public updateSize() {
+ const simLevel = this.simMain.currentLevel;
+ if (simLevel == null) {
+ return;
+ }
- const gdLevel = this.gdRoot.levels[simLevel.index];
- const minSize = Math.min(this.visMain.canvas.height, this.visMain.canvas.width * Math.sqrt(3) / 2);
- this.hexSize = Math.floor(minSize / (4 * (gdLevel.radius - 1) - 4));
- this.screenCellHeight = Math.ceil(2 * this.hexSize);
- this.screenCellHeight = Math.ceil(this.screenCellHeight * 0.5) * 2;
- this.screenCellWidth = Math.ceil(Math.sqrt(3) / 2 * this.screenCellHeight);
- this.screenCellWidth = Math.ceil(this.screenCellWidth * 0.5) * 2;
- this.screenXOffset = this.screenCellWidth * (gdLevel.radius + 0.5);
- this.screenYOffset = this.screenCellHeight * (gdLevel.radius + 0.5);
+ const gdLevel = this.gdRoot.levels[simLevel.index];
+ const minSize = Math.min(this.visMain.canvas.height, (this.visMain.canvas.width * Math.sqrt(3)) / 2);
+ this.hexSize = Math.floor(minSize / (4 * (gdLevel.radius - 1) - 4));
+ this.screenCellHeight = Math.ceil(2 * this.hexSize);
+ this.screenCellHeight = Math.ceil(this.screenCellHeight * 0.5) * 2;
+ this.screenCellWidth = Math.ceil((Math.sqrt(3) / 2) * this.screenCellHeight);
+ this.screenCellWidth = Math.ceil(this.screenCellWidth * 0.5) * 2;
+ this.screenXOffset = this.screenCellWidth * (gdLevel.radius + 0.5);
+ this.screenYOffset = this.screenCellHeight * (gdLevel.radius + 0.5);
- const width = this.screenCellWidth * (gdLevel.radius * 2 + 1);
- const height = this.screenCellHeight * (gdLevel.radius * 2 + 1);
- this.screenXOffset += (this.visMain.canvas.width - width) * 0.5;
- this.screenYOffset += (this.visMain.canvas.height - height) * 0.5;
+ const width = this.screenCellWidth * (gdLevel.radius * 2 + 1);
+ const height = this.screenCellHeight * (gdLevel.radius * 2 + 1);
+ this.screenXOffset += (this.visMain.canvas.width - width) * 0.5;
+ this.screenYOffset += (this.visMain.canvas.height - height) * 0.5;
- this.screenXOffset = Math.floor(this.screenXOffset);
- this.screenYOffset = Math.floor(this.screenYOffset);
- this.background = null;
- this.enemyMap.clear();
- }
+ this.screenXOffset = Math.floor(this.screenXOffset);
+ this.screenYOffset = Math.floor(this.screenYOffset);
+ this.background = null;
+ this.enemyMap.clear();
+ }
- public updateEveryFrame(currentStep: number) {
- const simLevel = this.simMain.currentLevel;
- if (simLevel == null) {
- return;
- }
+ public updateEveryFrame(currentStep: number) {
+ if (currentStep < 0) {
+ this.lastStep = -1;
+ return;
+ }
- const t = currentStep - Math.floor(currentStep);
+ const simLevel = this.simMain.currentLevel;
+ if (simLevel == null) {
+ return;
+ }
- const deadEnemies: SimEnemy[] = [];
- simLevel.enemies.forEach((simEnemy: SimEnemy) => {
- if (simEnemy.dead) {
- deadEnemies.push(simEnemy);
- return;
- }
+ const t = currentStep - Math.floor(currentStep);
- const visEnemy = this.enemyMap.get(simEnemy);
- if (!visEnemy) {
- this.enemyMap.set(simEnemy, new VisEnemy(this.gdRoot, this.assets, simEnemy, this.screenCellWidth, this.screenCellHeight));
- }
- else if (Math.floor(currentStep) != Math.floor(this.lastStep)) {
- visEnemy.advanceStep();
- }
- else {
- visEnemy.update(t);
- }
- });
- for (const deadEnemy of deadEnemies) {
- this.enemyMap.delete(deadEnemy);
- }
+ const deadEnemies: SimEnemy[] = [];
+ simLevel.enemies.forEach((simEnemy: SimEnemy) => {
+ if (simEnemy.dead) {
+ deadEnemies.push(simEnemy);
+ return;
+ }
- const deadProjectiles: SimProjectile[] = [];
- simLevel.projectiles.forEach((simProjectile: SimProjectile) => {
- if (simProjectile.dead) {
- deadProjectiles.push(simProjectile);
- return;
- }
+ const visEnemy = this.enemyMap.get(simEnemy);
+ if (!visEnemy) {
+ this.enemyMap.set(simEnemy, new VisEnemy(this.gdRoot, this.assets, simEnemy, this.screenCellWidth, this.screenCellHeight));
+ } else if (Math.floor(currentStep) != Math.floor(this.lastStep)) {
+ visEnemy.advanceStep();
+ } else {
+ visEnemy.update(t);
+ }
+ });
+ for (const deadEnemy of deadEnemies) {
+ this.enemyMap.delete(deadEnemy);
+ }
- const visProjectile = this.projectileMap.get(simProjectile);
- if (!visProjectile) {
- this.projectileMap.set(simProjectile, new VisProjectile(simProjectile));
- }
- else if (Math.floor(currentStep) != Math.floor(this.lastStep)) {
- visProjectile.advanceStep();
- }
- });
- for (const deadProjectile of deadProjectiles) {
- this.projectileMap.delete(deadProjectile);
- }
+ const deadProjectiles: SimProjectile[] = [];
+ simLevel.projectiles.forEach((simProjectile: SimProjectile) => {
+ if (simProjectile.dead) {
+ deadProjectiles.push(simProjectile);
+ return;
+ }
- this.lastStep = currentStep;
- }
+ const visProjectile = this.projectileMap.get(simProjectile);
+ if (!visProjectile) {
+ this.projectileMap.set(simProjectile, new VisProjectile(simProjectile));
+ } else if (Math.floor(currentStep) != Math.floor(this.lastStep)) {
+ visProjectile.advanceStep();
+ }
+ });
+ for (const deadProjectile of deadProjectiles) {
+ this.projectileMap.delete(deadProjectile);
+ }
- public setHoveredHex(hex: Hex | null) {
- this.hoveredHex = hex;
- }
+ this.lastStep = currentStep;
+ }
- public getScreenCoords(hex: Hex): Vector2 {
- const coord = Hex.toPixel(hex, this.hexSize);
- return new Vector2(coord.x + this.screenXOffset - this.screenCellWidth / 2, coord.y + this.screenYOffset - this.screenCellHeight / 2);
- }
+ public setHoveredHex(hex: Hex | null) {
+ this.hoveredHex = hex;
+ }
- public getHexFromScreenCoords(coords: Vector2): Hex {
- const x = coords.x - this.screenXOffset;
- const y = coords.y - this.screenYOffset;
- return Hex.fromPixel(new Vector2(x, y), this.hexSize);
- }
+ public getScreenCoords(hex: Hex): Vector2 {
+ const coord = Hex.toPixel(hex, this.hexSize);
+ return new Vector2(coord.x + this.screenXOffset - this.screenCellWidth / 2, coord.y + this.screenYOffset - this.screenCellHeight / 2);
+ }
- private drawBackground() {
- const ctx = this.visMain.context;
- const simLevel = this.simMain.currentLevel;
- if (simLevel == null) {
- return;
- }
+ public getHexFromScreenCoords(coords: Vector2): Hex {
+ const x = coords.x - this.screenXOffset;
+ const y = coords.y - this.screenYOffset;
+ return Hex.fromPixel(new Vector2(x, y), this.hexSize);
+ }
- const gdLevel = this.gdRoot.levels[simLevel.index];
- if (this.background == null) {
- const backgroundCanvas = this.visMain.canvas.cloneNode() as HTMLCanvasElement;
- const backgroundContext = backgroundCanvas.getContext("2d")!;
- this.background = backgroundCanvas;
- simLevel.cells.forEach((cell: SimCell) => {
- if (cell.distance > gdLevel.radius) {
- return;
- }
- if (cell.blockedType != -1 && cell.type == ECellType.Blocked) {
- this.drawCellImage(backgroundContext, cell, "cell-blocked-" + (cell.blockedType | 0) + ".svg");
- }
- });
+ private drawBackground() {
+ const ctx = this.visMain.context;
+ const simLevel = this.simMain.currentLevel;
+ if (simLevel == null) {
+ return;
+ }
- backgroundContext.globalCompositeOperation = "source-atop";
- backgroundContext.fillStyle = this.visMain.wallPattern;
- backgroundContext.fillRect(0, 0, this.visMain.canvas.width, this.visMain.canvas.height);
+ const gdLevel = this.gdRoot.levels[simLevel.index];
+ if (this.background == null) {
+ const backgroundCanvas = this.visMain.canvas.cloneNode() as HTMLCanvasElement;
+ const backgroundContext = backgroundCanvas.getContext('2d')!;
+ this.background = backgroundCanvas;
+ simLevel.cells.forEach((cell: SimCell) => {
+ if (cell.distance > gdLevel.radius) {
+ return;
+ }
+ if (cell.blockedType != -1 && cell.type == ECellType.Blocked) {
+ this.drawCellImage(backgroundContext, cell, 'cell-blocked-' + (cell.blockedType | 0) + '.svg');
+ }
+ });
- const cellCanvas = this.visMain.canvas.cloneNode() as HTMLCanvasElement;
- const cellContext = cellCanvas.getContext("2d")!;
- simLevel.cells.forEach((cell: SimCell) => {
- if (cell.distance > gdLevel.radius) {
- return;
- }
- if (cell.type != ECellType.Entry) {
- this.drawCellImage(cellContext, cell, "cell.svg");
- }
- });
- backgroundContext.globalCompositeOperation = "destination-over";
- backgroundContext.drawImage(cellCanvas, 0, 0);
- backgroundContext.globalCompositeOperation = "source-over";
- }
+ backgroundContext.globalCompositeOperation = 'source-atop';
+ backgroundContext.fillStyle = this.visMain.wallPattern;
+ backgroundContext.fillRect(0, 0, this.visMain.canvas.width, this.visMain.canvas.height);
- ctx.drawImage(this.background, 0, 0);
- }
+ const cellCanvas = this.visMain.canvas.cloneNode() as HTMLCanvasElement;
+ const cellContext = cellCanvas.getContext('2d')!;
+ simLevel.cells.forEach((cell: SimCell) => {
+ if (cell.distance > gdLevel.radius) {
+ return;
+ }
+ if (cell.type != ECellType.Entry) {
+ this.drawCellImage(cellContext, cell, 'cell.svg');
+ }
+ });
+ backgroundContext.globalCompositeOperation = 'destination-over';
+ backgroundContext.drawImage(cellCanvas, 0, 0);
+ backgroundContext.globalCompositeOperation = 'source-over';
+ }
- private drawProjectile(simProjectile: SimProjectile) {
- const visProjectile = this.projectileMap.get(simProjectile);
- if (!visProjectile) {
- return;
- }
- const t = this.lastStep - Math.floor(this.lastStep);
- const positions = visProjectile.positions;
- if (!positions) {
- return;
- }
- const pos = Vector2.lerp(positions[0], positions[1], t);
- const width = this.screenCellWidth * simProjectile.size;
- const height = this.screenCellHeight * simProjectile.size;
- this.visMain.context.drawImage(this.assets.getImage("images/projectile.svg"),
- this.screenXOffset + pos.x * this.hexSize - width / 2,
- this.screenYOffset + pos.y * this.hexSize - height / 2,
- width,
- height);
- }
+ ctx.drawImage(this.background, 0, 0);
+ }
- private drawEnemy(simEnemy: SimEnemy) {
- const visEnemy = this.enemyMap.get(simEnemy);
- if (!visEnemy) {
- return;
- }
- const t = this.lastStep - Math.floor(this.lastStep);
- const positions = visEnemy.positions;
- if (!positions) {
- return;
- }
- const pos = Vector2.lerp(positions[0], positions[1], t);
- this.visMain.context.drawImage(
- visEnemy.image,
- this.screenXOffset + pos.x * this.hexSize - this.screenCellWidth / 2,
- this.screenYOffset + pos.y * this.hexSize - this.screenCellHeight / 2,
- this.screenCellWidth,
- this.screenCellHeight);
- }
+ private drawProjectile(simProjectile: SimProjectile) {
+ const visProjectile = this.projectileMap.get(simProjectile);
+ if (!visProjectile) {
+ return;
+ }
+ const t = this.lastStep - Math.floor(this.lastStep);
+ const positions = visProjectile.positions;
+ if (!positions) {
+ return;
+ }
+ const pos = Vector2.lerp(positions[0], positions[1], t);
+ const width = this.screenCellWidth * simProjectile.size;
+ const height = this.screenCellHeight * simProjectile.size;
+ this.visMain.context.drawImage(this.assets.getImage('images/projectile.svg'), this.screenXOffset + pos.x * this.hexSize - width / 2, this.screenYOffset + pos.y * this.hexSize - height / 2, width, height);
+ }
- private drawCell(cell: SimCell) {
- const simLevel = this.simMain.currentLevel;
- if (simLevel == null) {
- return;
- }
+ private drawEnemy(simEnemy: SimEnemy) {
+ const visEnemy = this.enemyMap.get(simEnemy);
+ if (!visEnemy) {
+ return;
+ }
+ const t = this.lastStep - Math.floor(this.lastStep);
+ const positions = visEnemy.positions;
+ if (!positions) {
+ return;
+ }
+ const pos = Vector2.lerp(positions[0], positions[1], t);
+ this.visMain.context.drawImage(visEnemy.image, this.screenXOffset + pos.x * this.hexSize - this.screenCellWidth / 2, this.screenYOffset + pos.y * this.hexSize - this.screenCellHeight / 2, this.screenCellWidth, this.screenCellHeight);
+ }
- this.visMain.context.fillStyle = "rgba(192, 192, 192, 0.25)";
- if (cell.type == ECellType.Entry) {
- this.drawCellImage(this.visMain.context, cell, "cell-entry-" + (cell.blockedType | 0) + ".svg");
- }
+ private drawCell(cell: SimCell) {
+ const simLevel = this.simMain.currentLevel;
+ if (simLevel == null) {
+ return;
+ }
- const highlightedCell = simLevel.cells[simLevel.highlightedIndex];
- if (!!highlightedCell) {
- let draw = highlightedCell.index == cell.index;
- if (draw && highlightedCell.pathsToTarget != null) {
- for (const routeIdx in highlightedCell.pathsToTarget) {
- for (const idx in highlightedCell.pathsToTarget[routeIdx]) {
- if (highlightedCell.pathsToTarget[routeIdx][idx] == highlightedCell.index) {
- draw = true;
- break;
- }
- }
- }
- }
- if (draw) {
- this.drawCellImage(this.visMain.context, highlightedCell, "cell-highlighted.svg");
- this.visMain.context.fillStyle = "rgba(0, 0, 0, 1)";
- }
- }
- if (cell.tower != null) {
- this.drawCellImage(this.visMain.context, cell, "tower-" + (cell.tower.index | 0) + ".svg");
- }
+ this.visMain.context.fillStyle = 'rgba(192, 192, 192, 0.25)';
+ if (cell.type == ECellType.Entry) {
+ this.drawCellImage(this.visMain.context, cell, 'cell-entry-' + (cell.blockedType | 0) + '.svg');
+ }
- const coords = this.getScreenCoords(cell.hex);
- this.visMain.context.fillText("(" + cell.hex.col + ", " + cell.hex.row + ")", coords.x + 10, coords.y + this.screenCellHeight / 2 + 5);
- }
+ const highlightedCell = simLevel.cells[simLevel.highlightedIndex];
+ if (!!highlightedCell) {
+ let draw = highlightedCell.index == cell.index;
+ if (draw && highlightedCell.pathsToTarget != null) {
+ for (const routeIdx in highlightedCell.pathsToTarget) {
+ for (const idx in highlightedCell.pathsToTarget[routeIdx]) {
+ if (highlightedCell.pathsToTarget[routeIdx][idx] == highlightedCell.index) {
+ draw = true;
+ break;
+ }
+ }
+ }
+ }
+ if (draw) {
+ this.drawCellImage(this.visMain.context, highlightedCell, 'cell-highlighted.svg');
+ this.visMain.context.fillStyle = 'rgba(0, 0, 0, 1)';
+ }
+ }
+ if (cell.tower != null) {
+ this.drawCellImage(this.visMain.context, cell, 'tower-' + (cell.tower.index | 0) + '.svg');
+ }
- private drawCellImage(context: CanvasRenderingContext2D, cell: SimCell, name: string) {
- const coords = this.getScreenCoords(cell.hex);
- context.drawImage(this.assets.getImage("images/" + name), coords.x, coords.y, this.screenCellWidth, this.screenCellHeight);
- }
+ const coords = this.getScreenCoords(cell.hex);
+ this.visMain.context.fillText('(' + cell.hex.col + ', ' + cell.hex.row + ')', coords.x + 10, coords.y + this.screenCellHeight / 2 + 5);
+ }
+
+ private drawCellImage(context: CanvasRenderingContext2D, cell: SimCell, name: string) {
+ const coords = this.getScreenCoords(cell.hex);
+ context.drawImage(this.assets.getImage('images/' + name), coords.x, coords.y, this.screenCellWidth, this.screenCellHeight);
+ }
}
diff --git a/src/app/components/game/vis/VisMain.ts b/src/app/components/game/vis/VisMain.ts
index 553d8df..30946b7 100644
--- a/src/app/components/game/vis/VisMain.ts
+++ b/src/app/components/game/vis/VisMain.ts
@@ -19,6 +19,7 @@ export class VisMain {
private startTimestamp: number = 0;
private ready: boolean = false;
private gap: number = 0;
+ private animationFrameId: number | null = null;
constructor(simMain: SimMain, assets: AssetPreloaderService, wrapper: HTMLDivElement, canvas: HTMLCanvasElement) {
this.assets = assets;
@@ -50,7 +51,7 @@ export class VisMain {
return;
}
- requestAnimationFrame((timestamp: number) => {
+ this.animationFrameId = requestAnimationFrame((timestamp: number) => {
this.step(timestamp);
});
@@ -105,11 +106,17 @@ export class VisMain {
stop() {
this.active = false;
+ this.startTimestamp = 0;
+ this.visLevel.updateEveryFrame(-1);
+ if (this.animationFrameId !== null) {
+ cancelAnimationFrame(this.animationFrameId);
+ this.animationFrameId = null;
+ }
}
start() {
this.active = true;
- requestAnimationFrame((timestamp: number) => {
+ this.animationFrameId = requestAnimationFrame((timestamp: number) => {
this.startTimestamp = timestamp - (this.simMain.currentStep / this.simMain.gdRoot.simulation.stepsPerSecond) * 1000;
this.step(timestamp);
});