Add Golem boss wave 10 with clear-arena requirement
This commit is contained in:
+51
-13
@@ -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);
|
||||||
this.uiWaveBarFill.style.width = `${wavePct * 100}%`;
|
if (this.bossFightActive) {
|
||||||
this.uiWaveBarLabel.textContent = `Next Wave: ${Math.ceil(SPAWN_TIME - this.spawnTimer)}s`;
|
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.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,20 +1211,32 @@ 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) {
|
||||||
this.spawns++;
|
// Boss besiegt -> naechste Welle startet
|
||||||
if (this.spawns % 5 === 0) {
|
if (arenaCleared) {
|
||||||
const x = (Math.random() - 0.5) * 80;
|
this.bossFightActive = false;
|
||||||
const z = (Math.random() - 0.5) * 80;
|
this.spawns++;
|
||||||
this.spawnEnemyInstance(new Boss(), x, z, 0.15);
|
this.spawnTimer = 0;
|
||||||
playSound('spawn', 0.8);
|
}
|
||||||
|
} else if (this.spawnTimer >= SPAWN_TIME) {
|
||||||
|
if (this.isBossWave(this.spawns + 1)) {
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
Reference in New Issue
Block a user