56 lines
2.4 KiB
JavaScript
56 lines
2.4 KiB
JavaScript
// Serializes a level data object (as produced by levelBuilder.js) into the
|
|
// literal `export default {...}` JS module source text the game expects to
|
|
// find in src/data/levels/levelNN.js. Numbers are emitted as plain scaled
|
|
// literals rather than `N * WORLD_SCALE` expressions - levelBuilder.js has
|
|
// already fully resolved them, and level03.js already sets precedent for a
|
|
// level file built from computed literal points rather than hand-picked
|
|
// base-unit expressions.
|
|
|
|
function pointsLiteral(points, indent) {
|
|
const lines = points.map((p) => `${indent} { x: ${p.x}, y: ${p.y} },`);
|
|
return `[\n${lines.join('\n')}\n${indent}]`;
|
|
}
|
|
|
|
function terrainLiteral(terrain) {
|
|
const segments = terrain.map((segment) => ` { points: ${pointsLiteral(segment.points, ' ')} },`);
|
|
return `[\n${segments.join('\n')}\n ]`;
|
|
}
|
|
|
|
function rectLiteral(rect) {
|
|
return `{ x: ${rect.x}, y: ${rect.y}, width: ${rect.width}, height: ${rect.height} }`;
|
|
}
|
|
|
|
// Smashable item placements (editor "Smashables" section) - one literal
|
|
// object per item, same field order as levelBuilder.js emits them.
|
|
function itemsLiteral(items) {
|
|
if (!items || items.length === 0) return '[]';
|
|
const lines = items.map(
|
|
(it) => ` { type: ${JSON.stringify(it.type)}, mode: ${JSON.stringify(it.mode)}, x: ${it.x}, y: ${it.y} },`
|
|
);
|
|
return `[\n${lines.join('\n')}\n ]`;
|
|
}
|
|
|
|
export function exportLevelToSource(levelData) {
|
|
const lines = [
|
|
'// Generated by editor.html - review before dropping into src/data/levels/.',
|
|
'export default {',
|
|
` id: ${JSON.stringify(levelData.id)},`,
|
|
` name: ${JSON.stringify(levelData.name)},`,
|
|
` description: ${JSON.stringify(levelData.description)},`,
|
|
` kidsAboard: ${levelData.kidsAboard},`,
|
|
` timeLimit: ${levelData.timeLimit},`,
|
|
` startPosition: { x: ${levelData.startPosition.x}, y: ${levelData.startPosition.y} },`,
|
|
` startAngle: ${levelData.startAngle},`,
|
|
` terrain: ${terrainLiteral(levelData.terrain)},`,
|
|
' obstacles: [],',
|
|
// Only emitted when the level actually has items - keeps hand-authored
|
|
// levels' exports byte-identical to before this feature existed.
|
|
...(levelData.items && levelData.items.length > 0 ? [` items: ${itemsLiteral(levelData.items)},`] : []),
|
|
` goal: ${rectLiteral(levelData.goal)},`,
|
|
` cameraBounds: ${rectLiteral(levelData.cameraBounds)},`,
|
|
'};',
|
|
'',
|
|
];
|
|
return lines.join('\n');
|
|
}
|