slop game oder so
This commit is contained in:
@@ -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 };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user