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
+79
View File
@@ -0,0 +1,79 @@
/**
* Aufbau der Arena: Boden, Dekoration und Begrenzung.
*
* Mit geladenen Kenney-Kacheln entsteht ein Erdboden mit Felsen, fremdartiger Flora
* und Flecken; ohne sie ein einfaches Schachbrett-Platzhaltermuster. Dekoration hat
* keine Physik – sie soll nur den Boden lebendig machen, nicht den Weg versperren.
* @module systems/Arena
*/
import { COLORS, GAME } from '../config.js';
import { pick, randFloat, randInt } from '../logic/rng.js';
import { GROUND_FRAMES, GROUND_SHEET } from './Assets.js';
import { TEXTURE_KEYS } from './Placeholders.js';
/** Abdunkelung des Bodens, damit Figuren und Projektile sich klar abheben. */
const GROUND_TINT = 0x6f6458;
/** Anzahl Deko-Objekte je Sorte (für eine 2400×1600-Arena abgestimmt). */
const DECOR = Object.freeze({ dirtPatches: 180, rocks: 45, bushes: 28, splats: 14 });
/** Flora und Flecken in „außerirdischen“ Farben statt Erdgrün. */
const ALIEN_TINTS = Object.freeze([0x6d5a8f, 0x3f7f78, 0x7d5f86]);
const SPLAT_TINT = 0x2f4a1a;
/** Freiraum um die Startposition, damit dort nichts die Sicht stört. */
const CLEAR_RADIUS = 180;
/**
* @param {Phaser.Scene} scene
* @param {() => number} rng
*/
export function buildArena(scene, rng) {
const { width, height } = GAME.world;
const depth = GAME.depth.ground;
if (scene.textures.exists(GROUND_SHEET.key)) {
const key = GROUND_SHEET.key;
const tile = GROUND_SHEET.frame;
scene.add.tileSprite(0, 0, width, height, key, GROUND_FRAMES.dirtA).setOrigin(0).setDepth(depth).setTint(GROUND_TINT);
// Zweite Erdsorte im Kachelraster verstreut: bricht das sichtbare Wiederholungsmuster.
for (let i = 0; i < DECOR.dirtPatches; i += 1) {
const x = randInt(rng, 0, Math.floor(width / tile) - 1) * tile;
const y = randInt(rng, 0, Math.floor(height / tile) - 1) * tile;
scene.add.image(x, y, key, GROUND_FRAMES.dirtB).setOrigin(0).setDepth(depth).setTint(GROUND_TINT);
}
const place = (frame, count, decorate) => {
for (let i = 0; i < count; i += 1) {
const point = randomPoint(rng, width, height);
const image = scene.add.image(point.x, point.y, key, frame(rng)).setDepth(depth + 1);
image.setAngle(randFloat(rng, 0, 360));
decorate(image);
}
};
place((r) => pick(r, GROUND_FRAMES.rocks), DECOR.rocks, (img) => img.setScale(randFloat(rng, 0.45, 0.95)).setTint(0x8d9196));
place((r) => pick(r, GROUND_FRAMES.bushes), DECOR.bushes, (img) => img.setScale(randFloat(rng, 0.5, 1.1)).setTint(pick(rng, ALIEN_TINTS)));
place(() => GROUND_FRAMES.splat, DECOR.splats, (img) => img.setScale(randFloat(rng, 0.8, 1.6)).setTint(SPLAT_TINT).setAlpha(0.7));
} else {
scene.add.tileSprite(0, 0, width, height, TEXTURE_KEYS.ground).setOrigin(0).setDepth(depth);
}
// Emblem der Vereinigten Erde als Bodenmarkierung der Landezone.
scene.add
.image(width / 2, height / 2, TEXTURE_KEYS.emblem)
.setDisplaySize(300, 300)
.setAlpha(0.14)
.setDepth(depth + 1);
const border = scene.add.graphics().setDepth(depth + 2);
border.lineStyle(10, COLORS.crimson, 0.9);
border.strokeRect(5, 5, width - 10, height - 10);
border.lineStyle(3, COLORS.gold, 0.9);
border.strokeRect(14, 14, width - 28, height - 28);
}
/** Zufallspunkt in der Arena außerhalb der freien Startzone. */
function randomPoint(rng, width, height) {
for (;;) {
const x = randFloat(rng, 30, width - 30);
const y = randFloat(rng, 30, height - 30);
if (Math.hypot(x - width / 2, y - height / 2) > CLEAR_RADIUS) return { x, y };
}
}