New heightfield kinds: hip/corner quarter, kicker (tunable concavity), roller, wedge/manny pad, volcano, round-bowl option, quarter vert extension. Rails are now polylines (kink/dbl-kink/rainbow/A-frame/pole-jam/donkey presets, round or square profile, per-node drag handles) that flatten to straight segments on export so bookquoy grind detection is untouched. 13 parametric street props (jersey barrier, picnic table, parking block, fence, floodlight, bleachers...). Palette regrouped TRANSITION/STREET/STEEL/PROPS; park check covers new kinds. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
50 lines
2.0 KiB
JavaScript
50 lines
2.0 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');
|
|
}
|
|
|
|
export function generateLevelJS(park) {
|
|
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);
|
|
|
|
export function buildLevel(scene) {
|
|
const { ground, letterMeshes } = buildParkScene(scene, PARK);
|
|
return { ground, letterMeshes };
|
|
}
|
|
`;
|
|
}
|
|
|
|
export function downloadLevelJS(park) {
|
|
download('level.' + slug(park) + '.js', generateLevelJS(park), 'text/javascript');
|
|
}
|