fixed dynamic enemy pathfinding

This commit is contained in:
2025-06-14 22:24:03 +02:00
parent 9b81bef804
commit d26999ace9
4 changed files with 34 additions and 17 deletions

View File

@@ -42,9 +42,6 @@ export class SimEnemy {
}
public onPathUpdated(level: SimLevel) {
const myPos = this.position;
this.currentPathPosition = myPos;
if (this.path == null) {
return;
}
@@ -58,7 +55,7 @@ export class SimEnemy {
const cells = level.cells;
const pos1 = cells[current].hex.toWorld();
const pos2 = cells[next].hex.toWorld();
const myDir = pos2.subtract(myPos);
const myDir = pos2.subtract(this.currentPathPosition);
const myLen = myDir.magnitude();
const hexDir = pos2.subtract(pos1);
const hexLen = hexDir.magnitude();

View File

@@ -143,16 +143,31 @@ export class SimLevel {
return false;
}
for (const routeIdx in gdLevel.enemyRoutes) {
const route = gdLevel.enemyRoutes[routeIdx];
const enemySpawnHex = gdLevel.enemySpawns[route[0]];
const enemySpawnCell = this.cells[this.getCellIndex(enemySpawnHex)];
enemySpawnCell.pathsToTarget[routeIdx] = newRoutePaths[routeIdx];
}
for (let idx in this.enemies) {
const simEnemy = this.enemies[idx];
const hex = Hex.fromWorld(simEnemy.position);
const startIndex = this.getCellIndex(hex);
const currentIndex = simEnemy.path[simEnemy.currentPathIndex];
const nextIndex = simEnemy.path[simEnemy.currentPathIndex + 1];
const nextCell = this.cells[nextIndex];
const endIndex = this.getCellIndex(simEnemy.endHex);
const path = PathFinding.bfs(this, startIndex, endIndex);
let startIndex = nextCell.type != ECellType.Free ? currentIndex : nextIndex;
let path = PathFinding.bfs(this, startIndex, endIndex);
if (path == null) {
invalid = true;
break;
}
if (nextCell.type != ECellType.Free) {
path = [nextIndex, ...path];
}
else {
path = [currentIndex, ...path];
}
newEnemyPaths[idx] = path;
}
@@ -160,15 +175,9 @@ export class SimLevel {
return false;
}
for (const routeIdx in gdLevel.enemyRoutes) {
const route = gdLevel.enemyRoutes[routeIdx];
const enemySpawnHex = gdLevel.enemySpawns[route[0]];
const enemySpawnCell = this.cells[this.getCellIndex(enemySpawnHex)];
enemySpawnCell.pathsToTarget[routeIdx] = newRoutePaths[routeIdx];
}
this.enemies.forEach((simEnemy: SimEnemy, idx: number) => {
simEnemy.path = newEnemyPaths[idx];
const newPath = newEnemyPaths[idx];
simEnemy.path = newPath;
simEnemy.currentPathIndex = 0;
simEnemy.onPathUpdated(this);
});

View File

@@ -19,8 +19,6 @@ export class SimActionMoveEnemies implements ISimAction {
}
for (const simEnemy of level.enemies) {
const duration = simEnemy.speed / simMain.gdRoot.simulation.stepsPerSecond;
const t = (level.currentStep - simEnemy.currentPathStep) * duration;
const path2 = level.cells[simEnemy.path[simEnemy.currentPathIndex + 1]];
if (!path2) {
simEnemy.dead = true;
@@ -30,11 +28,17 @@ export class SimActionMoveEnemies implements ISimAction {
const hex2 = path2.hex;
const pos1 = simEnemy.currentPathPosition;
const pos2 = Hex.toWorld(hex2);
const segmentLength = pos2.subtract(pos1).magnitude();
const stepsToTraverse = (segmentLength * simMain.gdRoot.simulation.stepsPerSecond) / simEnemy.speed;
const t = (level.currentStep - simEnemy.currentPathStep) / stepsToTraverse;
simEnemy.prevPosition = simEnemy.position;
simEnemy.position = Vector2.lerp(pos1, pos2, t);
if (t >= 1) {
simEnemy.currentPathIndex += 1;
simEnemy.currentPathStep = level.currentStep;
simEnemy.currentPathPosition = pos2.clone();
simEnemy.onPathUpdated(level);
}
}

View File

@@ -39,12 +39,19 @@ export class SimActionSpawnEnemies implements ISimAction {
simEnemy.startHex = gdLevel.enemySpawns[gdLevel.enemyRoutes[route][0]];
simEnemy.endHex = gdLevel.enemyTargets[gdLevel.enemyRoutes[route][1]];
simEnemy.position = Hex.toWorld(simEnemy.startHex);
simEnemy.currentPathPosition = simEnemy.position.clone();
simEnemy.prevPosition = simEnemy.position.clone();
const startIndex = level.getCellIndex(simEnemy.startHex);
const endIndex = level.getCellIndex(simEnemy.endHex);
const path = PathFinding.bfs(level, startIndex, endIndex);
simEnemy.path = path!;
simEnemy.currentPathIndex = 0;
simEnemy.speed = simMain.gdRoot.enemies[gdWave.enemy].speed;
simEnemy.currentPathStep = step;
simEnemy.hitPonts = 10; // TODO gd
simEnemy.size = EEnemySize.Tiny; // TODO gd
simEnemy.gain = 10; // TODO gd
simEnemy.onPathUpdated(level);
level.enemies.push(simEnemy);
}