Add Golem boss wave 10 with clear-arena requirement

This commit is contained in:
2026-08-19 10:51:05 +02:00
parent 5ceb37fdb4
commit 1a4cccda6e
2 changed files with 52 additions and 14 deletions
+48 -10
View File
@@ -8,7 +8,7 @@ import { Bat } from './Bat';
import { BeeSwarm } from './BeeSwarm'; import { BeeSwarm } from './BeeSwarm';
import { Slime } from './Slime'; import { Slime } from './Slime';
import { Brute } from './Brute'; import { Brute } from './Brute';
import { Boss } from './Boss'; import { Golem } from './Golem';
import { Crab } from './Crab'; import { Crab } from './Crab';
import { Turret } from './Turret'; import { Turret } from './Turret';
import { EnemyProjectile } from './EnemyProjectile'; import { EnemyProjectile } from './EnemyProjectile';
@@ -74,6 +74,10 @@ export class Game {
spawns = 0; spawns = 0;
killed = 0; killed = 0;
// Boss-Wellen: Welle -> Boss-Factory (aktuell nur Welle 10; 20/30 folgen)
private bossWaves = new Map<number, () => Enemy>([[10, () => new Golem()]]);
private bossFightActive = false;
// Debug hitzone visualization // Debug hitzone visualization
private showHitzones = false; private showHitzones = false;
private playerHitRing!: THREE.Mesh; private playerHitRing!: THREE.Mesh;
@@ -638,6 +642,7 @@ export class Game {
this.spawnTimer = 0; this.spawnTimer = 0;
this.spawns = 0; this.spawns = 0;
this.killed = 0; this.killed = 0;
this.bossFightActive = false;
this.pendingPicks = 0; this.pendingPicks = 0;
this.hideLevelUp(); this.hideLevelUp();
this.skillSystem = new SkillSystem(this.seed ?? 0); this.skillSystem = new SkillSystem(this.seed ?? 0);
@@ -831,6 +836,19 @@ export class Game {
return w; return w;
} }
private isBossWave(wave: number): boolean {
return this.bossWaves.has(wave);
}
private spawnBossForWave(wave: number) {
const factory = this.bossWaves.get(wave);
if (!factory) return;
const x = (Math.random() - 0.5) * 80;
const z = (Math.random() - 0.5) * 80;
this.spawnEnemyInstance(factory(), x, z, 0.15);
playSound('spawn', 0.8);
}
spawnEnemyInstance(enemy: Enemy, x: number, z: number, y: number) { spawnEnemyInstance(enemy: Enemy, x: number, z: number, y: number) {
enemy.body.position.set(x, y, z); enemy.body.position.set(x, y, z);
this.scene.add(enemy.body); this.scene.add(enemy.body);
@@ -1054,9 +1072,17 @@ export class Game {
const gasPct = Math.max(0, (gasTotal - this.trapper.cooldown2) / gasTotal); const gasPct = Math.max(0, (gasTotal - this.trapper.cooldown2) / gasTotal);
this.uiGasCD.style.width = `${gasPct * 100}%`; this.uiGasCD.style.width = `${gasPct * 100}%`;
const wavePct = this.spawnTimer / SPAWN_TIME; const wavePct = Math.min(1, this.spawnTimer / SPAWN_TIME);
if (this.bossFightActive) {
this.uiWaveBarFill.style.width = '100%';
this.uiWaveBarLabel.textContent = 'BOSS!';
} else if (this.spawnTimer >= SPAWN_TIME && this.isBossWave(this.spawns + 1)) {
this.uiWaveBarFill.style.width = '100%';
this.uiWaveBarLabel.textContent = 'Gegner räumen!';
} else {
this.uiWaveBarFill.style.width = `${wavePct * 100}%`; this.uiWaveBarFill.style.width = `${wavePct * 100}%`;
this.uiWaveBarLabel.textContent = `Next Wave: ${Math.ceil(SPAWN_TIME - this.spawnTimer)}s`; this.uiWaveBarLabel.textContent = `Next Wave: ${Math.ceil(SPAWN_TIME - this.spawnTimer)}s`;
}
if (this.player.health <= 0 && this.state === 'playing') { if (this.player.health <= 0 && this.state === 'playing') {
this.gameOver(); this.gameOver();
@@ -1185,21 +1211,33 @@ export class Game {
// Spawn enemies in waves // Spawn enemies in waves
if (this.state === 'playing') { if (this.state === 'playing') {
this.spawnTimer += dt; const arenaCleared = this.enemies.every(e => e.dead);
if (this.spawnTimer >= SPAWN_TIME) { if (this.bossFightActive) {
// Boss besiegt -> naechste Welle startet
if (arenaCleared) {
this.bossFightActive = false;
this.spawns++; this.spawns++;
if (this.spawns % 5 === 0) { this.spawnTimer = 0;
const x = (Math.random() - 0.5) * 80; }
const z = (Math.random() - 0.5) * 80; } else if (this.spawnTimer >= SPAWN_TIME) {
this.spawnEnemyInstance(new Boss(), x, z, 0.15); if (this.isBossWave(this.spawns + 1)) {
playSound('spawn', 0.8); // Boss-Welle startet erst, wenn alle Gegner tot sind
if (arenaCleared) {
this.spawns++;
this.spawnBossForWave(this.spawns);
this.bossFightActive = true;
this.spawnTimer = 0;
}
} else { } else {
this.spawns++;
for (let i = 0; i < this.spawns; i++) { for (let i = 0; i < this.spawns; i++) {
this.spawnEnemy(); this.spawnEnemy();
} }
}
this.spawnTimer = 0; this.spawnTimer = 0;
} }
} else {
this.spawnTimer += dt;
}
} }
// Check close encounters (enemy touching player) // Check close encounters (enemy touching player)
+1 -1
View File
@@ -2,7 +2,7 @@ import * as THREE from 'three';
import type { Game } from './Game'; import type { Game } from './Game';
import { Brute } from './Brute'; import { Brute } from './Brute';
export class Boss extends Brute { export class Golem extends Brute {
constructor() { constructor() {
super(); super();
this.health = 800; this.health = 800;