Extract engine setup
This commit is contained in:
@@ -26,6 +26,7 @@ Physilinks is a browser-based physics linking game built with Matter.js. Match a
|
|||||||
- `src/scenes/`: Scene presets split per file (`scene-*.js`) plus `index.js` that registers them to `window.PhysilinksScenes` (e.g., zero-G grid, balanced, low-G, fast drop, lava drift).
|
- `src/scenes/`: Scene presets split per file (`scene-*.js`) plus `index.js` that registers them to `window.PhysilinksScenes` (e.g., zero-G grid, balanced, low-G, fast drop, lava drift).
|
||||||
- `src/scenes/scene-template.js`: Reference-only template documenting every scene config option; not loaded by default.
|
- `src/scenes/scene-template.js`: Reference-only template documenting every scene config option; not loaded by default.
|
||||||
- `src/config.js`: Base game config defaults (gravity, spawn timing, link settings, palettes, message defaults).
|
- `src/config.js`: Base game config defaults (gravity, spawn timing, link settings, palettes, message defaults).
|
||||||
|
- `src/engine.js`: Matter engine/render/runner setup helpers (create, start/stop runner, resize render).
|
||||||
- `src/decomp-setup.js`: Registers `poly-decomp` with Matter to allow concave shapes (stars, blobs) built via `Bodies.fromVertices`.
|
- `src/decomp-setup.js`: Registers `poly-decomp` with Matter to allow concave shapes (stars, blobs) built via `Bodies.fromVertices`.
|
||||||
- `src/ui.js`: DOM access, HUD updates, overlays, popups, and control/selector wiring.
|
- `src/ui.js`: DOM access, HUD updates, overlays, popups, and control/selector wiring.
|
||||||
- `src/spawn.js`: Spawner utilities (intervals, batch/column/grid spawns), ball creation (shapes/blobs), radius scaling, and blob cleanup.
|
- `src/spawn.js`: Spawner utilities (intervals, batch/column/grid spawns), ball creation (shapes/blobs), radius scaling, and blob cleanup.
|
||||||
|
|||||||
@@ -106,6 +106,7 @@
|
|||||||
<script src="./src/scenes/scene-stack-blocks.js"></script>
|
<script src="./src/scenes/scene-stack-blocks.js"></script>
|
||||||
<script src="./src/scenes/index.js"></script>
|
<script src="./src/scenes/index.js"></script>
|
||||||
<script src="./src/config.js"></script>
|
<script src="./src/config.js"></script>
|
||||||
|
<script src="./src/engine.js"></script>
|
||||||
<script src="./src/scene-registry.js"></script>
|
<script src="./src/scene-registry.js"></script>
|
||||||
<script src="./src/ui.js"></script>
|
<script src="./src/ui.js"></script>
|
||||||
<script src="./src/storage.js"></script>
|
<script src="./src/storage.js"></script>
|
||||||
|
|||||||
73
src/engine.js
Normal file
73
src/engine.js
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
(() => {
|
||||||
|
const { Engine, Render, Runner } = Matter;
|
||||||
|
|
||||||
|
const create = ({
|
||||||
|
sceneEl,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
background = "transparent",
|
||||||
|
wireframes = false,
|
||||||
|
showAngleIndicator = false,
|
||||||
|
}) => {
|
||||||
|
const engine = Engine.create();
|
||||||
|
const render = Render.create({
|
||||||
|
element: sceneEl,
|
||||||
|
engine,
|
||||||
|
options: {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
wireframes,
|
||||||
|
background,
|
||||||
|
showAngleIndicator,
|
||||||
|
pixelRatio: window.devicePixelRatio || 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
Render.run(render);
|
||||||
|
|
||||||
|
const runner = Runner.create();
|
||||||
|
Runner.run(runner, engine);
|
||||||
|
let runnerActive = true;
|
||||||
|
|
||||||
|
const startRunner = () => {
|
||||||
|
if (!runnerActive) {
|
||||||
|
Runner.run(runner, engine);
|
||||||
|
runnerActive = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const stopRunner = () => {
|
||||||
|
if (runnerActive) {
|
||||||
|
Runner.stop(runner);
|
||||||
|
runnerActive = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const setRenderSize = (nextWidth, nextHeight) => {
|
||||||
|
const pixelRatio = window.devicePixelRatio || 1;
|
||||||
|
render.options.width = nextWidth;
|
||||||
|
render.options.height = nextHeight;
|
||||||
|
render.options.pixelRatio = pixelRatio;
|
||||||
|
render.canvas.style.width = `${nextWidth}px`;
|
||||||
|
render.canvas.style.height = `${nextHeight}px`;
|
||||||
|
render.canvas.width = nextWidth * pixelRatio;
|
||||||
|
render.canvas.height = nextHeight * pixelRatio;
|
||||||
|
Render.setPixelRatio(render, pixelRatio);
|
||||||
|
render.bounds.min.x = 0;
|
||||||
|
render.bounds.min.y = 0;
|
||||||
|
render.bounds.max.x = nextWidth;
|
||||||
|
render.bounds.max.y = nextHeight;
|
||||||
|
Render.lookAt(render, render.bounds);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
engine,
|
||||||
|
render,
|
||||||
|
runner,
|
||||||
|
startRunner,
|
||||||
|
stopRunner,
|
||||||
|
setRenderSize,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
window.PhysilinksEngine = { create };
|
||||||
|
})();
|
||||||
62
src/main.js
62
src/main.js
@@ -1,6 +1,5 @@
|
|||||||
(() => {
|
(() => {
|
||||||
const { Engine, Render, Runner, World, Body, Constraint, Events, Vector } =
|
const { World, Body, Constraint, Events, Vector } = Matter;
|
||||||
Matter;
|
|
||||||
|
|
||||||
const { config: baseConfig, defaultMessageConfig } = window.PhysilinksConfig
|
const { config: baseConfig, defaultMessageConfig } = window.PhysilinksConfig
|
||||||
?.create
|
?.create
|
||||||
@@ -14,6 +13,7 @@
|
|||||||
colors: null,
|
colors: null,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
...baseConfig,
|
...baseConfig,
|
||||||
link: { ...(baseConfig?.link || {}) },
|
link: { ...(baseConfig?.link || {}) },
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
defaultSceneId,
|
defaultSceneId,
|
||||||
order: sceneOrder = [],
|
order: sceneOrder = [],
|
||||||
} = window.PhysilinksScenes || {};
|
} = window.PhysilinksScenes || {};
|
||||||
|
|
||||||
const { getSceneById, getSceneIdFromUrl, setSceneIdInUrl, getNextSceneId } =
|
const { getSceneById, getSceneIdFromUrl, setSceneIdInUrl, getNextSceneId } =
|
||||||
window.PhysilinksSceneRegistry || {};
|
window.PhysilinksSceneRegistry || {};
|
||||||
|
|
||||||
@@ -35,44 +36,20 @@
|
|||||||
let height = sceneEl.clientHeight;
|
let height = sceneEl.clientHeight;
|
||||||
const BALL_BASELINE = 680; // reference height used for relative ball sizing
|
const BALL_BASELINE = 680; // reference height used for relative ball sizing
|
||||||
|
|
||||||
const engine = Engine.create();
|
const { engine, render, runner, startRunner, stopRunner, setRenderSize } =
|
||||||
|
window.PhysilinksEngine.create({
|
||||||
|
sceneEl,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
background: "transparent",
|
||||||
|
wireframes: false,
|
||||||
|
showAngleIndicator: false,
|
||||||
|
});
|
||||||
const defaultGravityScale = engine.gravity.scale;
|
const defaultGravityScale = engine.gravity.scale;
|
||||||
const defaultTimeScale = engine.timing.timeScale || 1;
|
const defaultTimeScale = engine.timing.timeScale || 1;
|
||||||
engine.gravity.y = config.gravity;
|
engine.gravity.y = config.gravity;
|
||||||
const world = engine.world;
|
const world = engine.world;
|
||||||
|
|
||||||
const render = Render.create({
|
|
||||||
element: sceneEl,
|
|
||||||
engine,
|
|
||||||
options: {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
wireframes: false,
|
|
||||||
background: "transparent",
|
|
||||||
showAngleIndicator: false,
|
|
||||||
pixelRatio: window.devicePixelRatio || 1,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
Render.run(render);
|
|
||||||
|
|
||||||
const runner = Runner.create();
|
|
||||||
Runner.run(runner, engine);
|
|
||||||
let runnerActive = true;
|
|
||||||
|
|
||||||
const startRunner = () => {
|
|
||||||
if (!runnerActive) {
|
|
||||||
Runner.run(runner, engine);
|
|
||||||
runnerActive = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const stopRunner = () => {
|
|
||||||
if (runnerActive) {
|
|
||||||
Runner.stop(runner);
|
|
||||||
runnerActive = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Static boundaries and scene-specific obstacles.
|
// Static boundaries and scene-specific obstacles.
|
||||||
let boundaries = [];
|
let boundaries = [];
|
||||||
let rotators = [];
|
let rotators = [];
|
||||||
@@ -580,20 +557,7 @@
|
|||||||
const prevRadius = config.ballRadius;
|
const prevRadius = config.ballRadius;
|
||||||
width = sceneEl.clientWidth;
|
width = sceneEl.clientWidth;
|
||||||
height = sceneEl.clientHeight;
|
height = sceneEl.clientHeight;
|
||||||
const pixelRatio = window.devicePixelRatio || 1;
|
setRenderSize(width, height);
|
||||||
render.options.width = width;
|
|
||||||
render.options.height = height;
|
|
||||||
render.options.pixelRatio = pixelRatio;
|
|
||||||
render.canvas.style.width = `${width}px`;
|
|
||||||
render.canvas.style.height = `${height}px`;
|
|
||||||
render.canvas.width = width * pixelRatio;
|
|
||||||
render.canvas.height = height * pixelRatio;
|
|
||||||
Render.setPixelRatio(render, pixelRatio);
|
|
||||||
render.bounds.min.x = 0;
|
|
||||||
render.bounds.min.y = 0;
|
|
||||||
render.bounds.max.x = width;
|
|
||||||
render.bounds.max.y = height;
|
|
||||||
Render.lookAt(render, render.bounds);
|
|
||||||
spawnSystem.updateBallRadius(prevRadius);
|
spawnSystem.updateBallRadius(prevRadius);
|
||||||
clampBodiesIntoView(prevWidth, prevHeight);
|
clampBodiesIntoView(prevWidth, prevHeight);
|
||||||
rebuildSceneBodies();
|
rebuildSceneBodies();
|
||||||
|
|||||||
Reference in New Issue
Block a user