slop game oder so

This commit is contained in:
2026-09-24 17:57:54 +02:00
commit 4c997eee21
166 changed files with 14976 additions and 0 deletions
+85
View File
@@ -0,0 +1,85 @@
/**
* Bodenmarkierung für verzögerte Einschläge (Orbital-Befehle, Mörser).
*
* Die Markierung zeigt den tatsächlichen Wirkungsradius und füllt sich bis zum
* Einschlag – so kann der Spieler Gefahr erkennen und ausweichen.
* @module systems/GroundMarker
*/
import { GAME } from '../config.js';
import { UI } from '../ui/theme.js';
export class GroundMarker {
/**
* @param {Phaser.Scene} scene
* @param {number} x
* @param {number} y
* @param {number} radius
* @param {number} color
* @param {number} startAt Spielzeit bei Erstellung.
* @param {number} impactAt Spielzeit des Einschlags.
* @param {{label?: string, beam?: boolean}} [options]
*/
constructor(scene, x, y, radius, color, startAt, impactAt, options = {}) {
this.scene = scene;
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.startAt = startAt;
this.impactAt = impactAt;
this.beam = options.beam ?? false;
this.graphics = scene.add.graphics().setDepth(GAME.depth.markers);
this.label = options.label
? scene.add
.text(x, y, '', {
fontFamily: UI.uiFont,
fontStyle: 'bold',
fontSize: '16px',
color: '#f4ecd8',
stroke: '#0d1321',
strokeThickness: 4,
})
.setOrigin(0.5)
.setDepth(GAME.depth.markers + 1)
: null;
this.labelText = options.label ?? '';
}
/**
* Zeichnet den aktuellen Zustand.
* @param {number} now
*/
update(now) {
const total = Math.max(1, this.impactAt - this.startAt);
const progress = Math.min(1, Math.max(0, (now - this.startAt) / total));
// Puls wird zum Einschlag hin schneller – intuitive Warnung ohne Text.
const pulse = 0.5 + 0.5 * Math.sin(now / (120 - 80 * progress));
const g = this.graphics;
g.clear();
g.fillStyle(this.color, 0.12 + 0.1 * pulse);
g.fillCircle(this.x, this.y, this.radius);
g.fillStyle(this.color, 0.35);
g.fillCircle(this.x, this.y, this.radius * progress);
g.lineStyle(3, this.color, 0.6 + 0.4 * pulse);
g.strokeCircle(this.x, this.y, this.radius);
if (this.beam) {
g.lineStyle(2 + 6 * progress, this.color, 0.25 + 0.5 * progress);
g.lineBetween(this.x, this.y - 900, this.x, this.y);
}
if (this.label) {
const seconds = Math.max(0, (this.impactAt - now) / 1000).toFixed(1).replace('.', ',');
this.label.setText(`${this.labelText} ${seconds}`);
}
}
/** @param {number} now @returns {boolean} */
isDue(now) {
return now >= this.impactAt;
}
destroy() {
this.graphics.destroy();
this.label?.destroy();
}
}