Add reference scene template

This commit is contained in:
Daddy32
2025-12-15 17:29:39 +01:00
parent 9de08cbd60
commit 0bc834416f
3 changed files with 137 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
(() => {
const { Bodies } = Matter;
const scenes = (window.PhysilinksSceneDefs =
window.PhysilinksSceneDefs || []);
// Template scene example for authors. This file is NOT referenced by index.html,
// so it will not load into the game unless you add a script tag for it.
scenes.push({
id: "your-scene-id",
name: "Template Example (not loaded)",
config: {
// Core physics and pacing
gravity: 0.9, // vertical gravity (positive pulls down)
gravityScale: 1, // multiplier on world gravity; set per scene
timeScale: 1, // global step speed multiplier; slows/speeds simulation
spawnIntervalMs: 520, // auto-spawn cadence when enabled
autoSpawn: true, // set false for grid/manual spawn scenes
spawnLimit: null, // number; stop spawning once reached
// Spawn placement
spawnOrigin: "edge", // "edge" (random along top) or "center" (random around middle)
spawnJitter: 60, // radius of randomness when origin is "center"
spawnFrom: "top", // "top" (default) or "bottom" for rising spawns
spawnColumns: null, // number of columns to align spawns; enables grid-like lanes
spawnInset: 0, // uniform horizontal inset (pixels) applied to spawn area
spawnInsets: ({ width, height, world }) => {
// optional function returning { left, right } in pixels; can react to world.plugin
return { left: 0, right: 0 };
},
squarePlayArea: false, // true constrains spawn/fit to centered square (uses world.plugin.squareOffset if set)
sizeFromColumns: false, // true derives ball radius from available width and spawnColumns
spawnBatchMin: 1, // minimum balls per spawn tick
spawnBatchMax: 1, // maximum balls per spawn tick
initialSpawnCount: 0, // number of balls to drop once at start (non-grid scenes)
initialRows: null, // with spawnColumns: seed rows x columns grid at start
rowGapMultiplier: 1.05, // spacing between seeded rows when initialRows is used
requireClearSpawn: false, // end run if spawn point is blocked
spawnIntervals: [
// Optional timed gravity schedule; main.js stores on world.plugin.stormSteps
// { seconds, gravityX, gravityY, label }
],
// Ball appearance/behavior
palette: ["#ff595e", "#ffca3a", "#8ac926", "#1982c4", "#6a4c93"], // colors used for balls (and legend)
ballRadius: 18, // baseline radius; may be rescaled per viewport
ballShape: "circle", // "circle" (default) or "rect"
blobBalls: false, // "soft" for soft-body clusters, "jagged" for rough polygons, or false for singles
// Chain/link rules
minChain: 3, // minimum balls to clear a chain
relaxMode: false, // true lets player link different colors
negativeScoreColors: [], // colors that invert score gain
negativeProgressColors: [], // colors that undo win-condition progress when cleared
link: {
stiffness: 0.85, // Matter constraint stiffness for links
lengthScale: 1.05, // stretch target relative to ball distance
damping: 0.08, // constraint damping
lineWidth: 3, // rendered link width
rope: true, // rope behavior: slack when short, taut when stretched
renderType: "line", // Matter render.type for constraints
maxLengthMultiplier: 3.1, // max link length as multiple of ball radius
maxLinkLength: null, // optional absolute pixel cap for link reach
},
// Messaging overlays (goal hints / milestones)
messages: {
durationMs: 4200, // how long floating messages persist
position: { xPercent: 50, yPercent: 10 }, // viewport-relative placement
text: null, // optional override for intro/progress text; falls back to goal-based text
colors: null, // optional array of gradient colors for message text
},
// Grid mode (used when gridLayouts is provided)
gridLayouts: [
// Each layout is an array of 8-character strings; non-space/period letters map to colors.
// Example: "AABBCCDD"
],
gridPadding: 0.08, // fraction of viewport used as padding on each side for grid playfield
gridBallScale: 0.36, // fraction of grid cell size to use as ball radius
gridLegend: {
// map letter -> hex color; falls back to palette when missing
// A: "#ff595e",
},
// Win conditions
winCondition: {
// Supported types:
// - "timer": survive durationSec seconds
// - "clearCount": clear target balls
// - "score": reach target score
// - "colorClear": clear specified counts per color in targets array
type: "score",
durationSec: 90, // timer length for "timer"
target: 10000, // score/clear target for "score" or "clearCount"
targets: [
// for "colorClear": { color, count }
// { color: "#ff595e", count: 12 },
],
onWin: {
// Optional celebratory effects applied on win:
shoveBalls: true, // random impulse burst
swirlBalls: false, // upward swirling nudge
disableGravity: false, // zero out gravity
setGravity: null, // number; set vertical gravity to value
removeCurves: false, // remove bodies tagged with plugin.curve
},
},
// Scoring/persistence
noGameOver: false, // true disables game-over-on-blocked-entry checks
},
createBodies: (w, h) => {
// Return an array of Matter bodies that make up scene obstacles/boundaries.
// Bodies can use plugin flags consumed by main.js:
// - plugin.rotSpeed: radians/sec; body will rotate each tick
// - plugin.oscillate: { axis: "x"|"y", amplitude, speed, phase } for sinusoidal motion
// - plugin.draggable: true to allow pointer dragging
// - plugin.curve: truthy marks for removal when winCondition.onWin.removeCurves is set
// - plugin.blobId: used automatically for soft/jagged blobs to clear as a group
const floorHeight = Math.max(60, h * 0.12);
return [
Bodies.rectangle(
w / 2,
h + floorHeight / 2,
w * 1.2,
floorHeight,
{
isStatic: true,
render: { fillStyle: "#0b1222", strokeStyle: "#0b1222" },
},
),
];
},
});
})();