js/kitthumbs.js renders each kit GLB to a 128x96 sprite once (offscreen renderer, framed by bounding sphere), POSTs to /api/kit-thumb, and all 52 are committed under assets/kit_thumbs/ so every checkout gets instant thumbs; the generator only runs for props without one (future kit drops). KIT drawer shows them with category groups and filter. js/colliders.js derives world-space colliders from kit manifest hints + a table for builtin props (bins, planters, trunks, fences...). Test ride resolves circle-vs-box/circle push-out — you scrub and stop instead of riding through furniture. Exports gain an additive COLLIDERS array for bookquoy to adopt when its player is ready; existing contract untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
55 lines
2.2 KiB
JavaScript
55 lines
2.2 KiB
JavaScript
// SKATEMAKER PRO — exports. A park leaves here two ways:
|
|
// 1. park.json — the native data format
|
|
// 2. level.<name>.js — a drop-in for BOOKQUOY: exports the exact interface
|
|
// bookquoy's js/level.js has (heightAt, normalAt, BOUNDS,
|
|
// RAILS, GAPS, LETTERS, SPAWN, buildLevel). Ship it with
|
|
// parkmath.js + parkbuild.js + assets/uploads/.
|
|
|
|
function download(name, text, type = 'application/octet-stream') {
|
|
const a = document.createElement('a');
|
|
a.href = URL.createObjectURL(new Blob([text], { type }));
|
|
a.download = name;
|
|
a.click();
|
|
setTimeout(() => URL.revokeObjectURL(a.href), 5000);
|
|
}
|
|
|
|
const slug = park => (park.name || 'park').toLowerCase().replace(/[^\w]+/g, '_');
|
|
|
|
export function downloadParkJSON(park) {
|
|
download(slug(park) + '.json', JSON.stringify(park, null, 1), 'application/json');
|
|
}
|
|
|
|
import { propColliders } from './colliders.js';
|
|
|
|
export function generateLevelJS(park, kitMap = {}) {
|
|
const colliders = propColliders(park, kitMap);
|
|
return `// ${park.name} — generated by SKATEMAKER PRO ${new Date().toISOString().slice(0, 10)}
|
|
// Drop-in for BOOKQUOY: copy this file + parkmath.js + parkbuild.js (+ assets/uploads/)
|
|
// into bookquoy/js/ and point main.js/player.js imports at it. Same contract as level.js:
|
|
// heightAt(x,z) is the single source of truth for visuals AND collision.
|
|
import { makeHeightAt, makeNormalAt, flattenRails } from './parkmath.js';
|
|
import { buildParkScene } from './parkbuild.js';
|
|
|
|
export const PARK = ${JSON.stringify(park, null, 1)};
|
|
|
|
export const BOUNDS = PARK.bounds;
|
|
export const RAILS = flattenRails(PARK);
|
|
export const GAPS = PARK.gaps;
|
|
export const LETTERS = PARK.letters;
|
|
export const SPAWN = PARK.spawn;
|
|
export const heightAt = makeHeightAt(PARK);
|
|
export const normalAt = makeNormalAt(heightAt);
|
|
// world-space prop colliders (bins, planters, trunks) — adopt when the player is ready
|
|
export const COLLIDERS = ${JSON.stringify(colliders)};
|
|
|
|
export function buildLevel(scene) {
|
|
const { ground, letterMeshes } = buildParkScene(scene, PARK);
|
|
return { ground, letterMeshes };
|
|
}
|
|
`;
|
|
}
|
|
|
|
export function downloadLevelJS(park, kitMap) {
|
|
download('level.' + slug(park) + '.js', generateLevelJS(park, kitMap), 'text/javascript');
|
|
}
|