Skip to content

Commit a1d70d3

Browse files
author
DavidQ
committed
Adding json files for tools editing.
1 parent d80b07d commit a1d70d3

11 files changed

Lines changed: 21355 additions & 191 deletions

samples/Phase 12 - Demo Games/Demo 1208 - Tool Formatted Tiles Parallax/ToolFormattedTilesParallaxScene.js

Lines changed: 168 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,19 @@ export default class ToolFormattedTilesParallaxScene extends Scene {
6868

6969
applyTileExportData(tileExport) {
7070
const tileset = tileExport?.tileset || null;
71-
const primaryLayer = Array.isArray(tileExport?.layers)
72-
? tileExport.layers.find((layer) => layer?.kind === 'tile-layer')
73-
: null;
74-
const cells = Array.isArray(primaryLayer?.cells)
75-
? primaryLayer.cells
76-
: (Array.isArray(tileExport?.cells) ? tileExport.cells : [[]]);
77-
const tileSize = Number(tileExport?.tileSize || tileset?.tileWidth) || 48;
71+
const atlas = extractTilesetAtlas(tileExport);
72+
const primaryLayer = getPrimaryTileLayer(tileExport);
73+
const cells = extractTileCells(tileExport, primaryLayer);
74+
const tileSize = extractTileSize(tileExport);
7875
const tilePalette = extractTileEntries(tileExport);
7976
const definitions = {};
80-
this.tilesetAssetPath = typeof tileset?.image === 'string' ? tileset.image : '';
77+
this.tilesetAssetPath = extractTilesetImagePath(tileExport, atlas);
8178
this.tilesetImage = null;
8279
this.tileFrameById = {};
80+
const atlasColumns = Number(atlas?.columns)
81+
|| ((Number(atlas?.imageWidth) > 0 && Number(atlas?.tileWidth) > 0)
82+
? Math.floor(Number(atlas.imageWidth) / Number(atlas.tileWidth))
83+
: 0);
8384

8485
for (const tileDefinition of tilePalette) {
8586
const tileId = Number(tileDefinition?.tileId ?? tileDefinition?.id);
@@ -98,8 +99,22 @@ export default class ToolFormattedTilesParallaxScene extends Scene {
9899
this.tileFrameById[tileId] = {
99100
x: Number(source.x) || 0,
100101
y: Number(source.y) || 0,
101-
w: Number(source.w) || tileSize,
102-
h: Number(source.h) || tileSize,
102+
w: Number(source.w ?? source.width) || tileSize,
103+
h: Number(source.h ?? source.height) || tileSize,
104+
};
105+
} else if (atlasColumns > 0 && tileId > 0) {
106+
const index = tileId - 1;
107+
const col = index % atlasColumns;
108+
const row = Math.floor(index / atlasColumns);
109+
const atlasTileWidth = Number(atlas?.tileWidth) || tileSize;
110+
const atlasTileHeight = Number(atlas?.tileHeight) || tileSize;
111+
const spacing = Number(atlas?.spacing) || 0;
112+
const margin = Number(atlas?.margin) || 0;
113+
this.tileFrameById[tileId] = {
114+
x: margin + col * (atlasTileWidth + spacing),
115+
y: margin + row * (atlasTileHeight + spacing),
116+
w: atlasTileWidth,
117+
h: atlasTileHeight,
103118
};
104119
}
105120

@@ -117,8 +132,7 @@ export default class ToolFormattedTilesParallaxScene extends Scene {
117132
height: this.tilemap.height * this.tilemap.tileSize,
118133
};
119134

120-
const viewportWidth = Number(tileExport?.camera?.viewportWidth) || 860;
121-
const viewportHeight = Number(tileExport?.camera?.viewportHeight) || 300;
135+
const { viewportWidth, viewportHeight } = extractCameraViewport(tileExport);
122136

123137
this.camera = new Camera2D({
124138
viewportWidth,
@@ -133,8 +147,7 @@ export default class ToolFormattedTilesParallaxScene extends Scene {
133147
this.world.height
134148
);
135149

136-
const spawn = tileExport?.spawnPoints?.hero
137-
|| tileExport?.heroSpawn
150+
const spawn = extractSpawnPoint(tileExport, tileSize, this.hero)
138151
|| { x: 120, y: this.world.height - tileSize - this.hero.height };
139152
this.hero.x = clamp(Number(spawn.x) || 120, 0, Math.max(0, this.world.width - this.hero.width));
140153
this.hero.y = clamp(
@@ -171,8 +184,16 @@ export default class ToolFormattedTilesParallaxScene extends Scene {
171184

172185
const loadOperations = layerDefinitions.map(async (layerDefinition, index) => {
173186
const image = await loadImageFromRelativePath(layerDefinition.asset, import.meta.url);
174-
const sourceWidth = image.naturalWidth || image.width;
175-
const sourceHeight = image.naturalHeight || image.height;
187+
const sourceWidth = Number(layerDefinition.sourceWidth)
188+
|| image.naturalWidth
189+
|| image.width
190+
|| Number(layerDefinition.segmentWidth)
191+
|| 1024;
192+
const sourceHeight = Number(layerDefinition.sourceHeight)
193+
|| image.naturalHeight
194+
|| image.height
195+
|| Number(layerDefinition.height)
196+
|| 300;
176197
return {
177198
id: layerDefinition.id || `layer-${index}`,
178199
image,
@@ -322,26 +343,13 @@ export default class ToolFormattedTilesParallaxScene extends Scene {
322343
}
323344

324345
drawParallax(renderer) {
325-
renderer.drawRect(
326-
this.screen.x,
327-
this.screen.y,
328-
this.camera.viewportWidth,
329-
this.camera.viewportHeight,
330-
'#9fd2ff'
331-
);
332-
renderer.drawCircle(
333-
this.screen.x + 160,
334-
this.screen.y + 54,
335-
28,
336-
'rgba(255, 245, 190, 0.75)'
337-
);
338-
339346
for (const layer of this.parallaxLayers) {
340-
const segment = layer.segmentWidth;
347+
const segment = Math.max(1, layer.segmentWidth);
341348
const offset = -((this.camera.x * layer.scrollFactor) % segment);
342349
const endX = this.screen.x + this.camera.viewportWidth + segment;
343350
const layerTop = this.screen.y + layer.y;
344-
const layerHeight = Math.max(1, this.camera.viewportHeight - layer.y);
351+
const viewportBottom = this.screen.y + this.camera.viewportHeight;
352+
const layerHeight = Math.max(1, viewportBottom - layerTop);
345353

346354
for (let x = this.screen.x + offset - segment; x < endX; x += segment) {
347355
renderer.drawImageFrame(
@@ -481,6 +489,18 @@ function getFallbackTileExport() {
481489
}
482490

483491
function extractTileEntries(tileExport) {
492+
if (tileExport?.schema === 'toolbox.tilemap/1' && Array.isArray(tileExport?.tileset)) {
493+
return tileExport.tileset
494+
.map((entry) => ({
495+
tileId: Number(entry?.id),
496+
name: entry?.name || `tile-${entry?.id}`,
497+
solid: Number(entry?.id) > 0,
498+
fallbackColor: entry?.color || '#1f2937',
499+
source: normalizeTilesetSource(entry?.source),
500+
}))
501+
.filter((entry) => Number.isInteger(entry.tileId) && entry.tileId > 0);
502+
}
503+
484504
if (Array.isArray(tileExport?.tileset?.entries)) {
485505
return tileExport.tileset.entries;
486506
}
@@ -499,3 +519,119 @@ function placePlatform(cells, row, startCol, endCol, tileId) {
499519
cells[row][col] = tileId;
500520
}
501521
}
522+
523+
function getPrimaryTileLayer(tileExport) {
524+
if (!Array.isArray(tileExport?.layers)) {
525+
return null;
526+
}
527+
if (tileExport?.schema === 'toolbox.tilemap/1') {
528+
return tileExport.layers.find((layer) => layer?.kind === 'tile') || null;
529+
}
530+
return tileExport.layers.find((layer) => layer?.kind === 'tile-layer') || null;
531+
}
532+
533+
function extractTileCells(tileExport, primaryLayer) {
534+
if (tileExport?.schema === 'toolbox.tilemap/1') {
535+
if (Array.isArray(primaryLayer?.data)) {
536+
return primaryLayer.data;
537+
}
538+
} else if (Array.isArray(primaryLayer?.cells)) {
539+
return primaryLayer.cells;
540+
}
541+
542+
if (Array.isArray(tileExport?.cells)) {
543+
return tileExport.cells;
544+
}
545+
return [[]];
546+
}
547+
548+
function extractTileSize(tileExport) {
549+
if (tileExport?.schema === 'toolbox.tilemap/1') {
550+
return Number(tileExport?.map?.tileSize)
551+
|| Number(tileExport?.tilesetAtlas?.tileWidth)
552+
|| 48;
553+
}
554+
return Number(tileExport?.tileSize || tileExport?.tileset?.tileWidth) || 48;
555+
}
556+
557+
function extractTilesetAtlas(tileExport) {
558+
if (tileExport?.schema === 'toolbox.tilemap/1') {
559+
return tileExport?.tilesetAtlas || null;
560+
}
561+
return tileExport?.tileset || null;
562+
}
563+
564+
function extractTilesetImagePath(tileExport, atlas) {
565+
if (typeof tileExport?.tileset?.image === 'string' && tileExport.tileset.image) {
566+
return tileExport.tileset.image;
567+
}
568+
if (typeof atlas?.imageName === 'string' && atlas.imageName) {
569+
return atlas.imageName;
570+
}
571+
if (typeof atlas?.imageDataUrl === 'string' && atlas.imageDataUrl) {
572+
return atlas.imageDataUrl;
573+
}
574+
return '';
575+
}
576+
577+
function extractCameraViewport(tileExport) {
578+
const markerCamera = Array.isArray(tileExport?.markers)
579+
? tileExport.markers.find((marker) => marker?.type === 'spawn' && marker?.properties)
580+
: null;
581+
582+
return {
583+
viewportWidth: Number(tileExport?.camera?.viewportWidth)
584+
|| Number(tileExport?.map?.viewportWidth)
585+
|| Number(markerCamera?.properties?.cameraViewportWidth)
586+
|| 860,
587+
viewportHeight: Number(tileExport?.camera?.viewportHeight)
588+
|| Number(tileExport?.map?.viewportHeight)
589+
|| Number(markerCamera?.properties?.cameraViewportHeight)
590+
|| 300,
591+
};
592+
}
593+
594+
function extractSpawnPoint(tileExport, tileSize, hero) {
595+
const explicit = tileExport?.spawnPoints?.hero || tileExport?.heroSpawn || null;
596+
if (explicit && Number.isFinite(Number(explicit.x)) && Number.isFinite(Number(explicit.y))) {
597+
return { x: Number(explicit.x), y: Number(explicit.y) };
598+
}
599+
600+
if (Array.isArray(tileExport?.markers)) {
601+
const spawnMarker = tileExport.markers.find((marker) => marker?.type === 'spawn');
602+
if (spawnMarker?.properties) {
603+
const px = Number(spawnMarker.properties.spawnX);
604+
const py = Number(spawnMarker.properties.spawnY);
605+
if (Number.isFinite(px) && Number.isFinite(py)) {
606+
return { x: px, y: py };
607+
}
608+
}
609+
if (spawnMarker && Number.isFinite(Number(spawnMarker.col)) && Number.isFinite(Number(spawnMarker.row))) {
610+
const col = Number(spawnMarker.col);
611+
const row = Number(spawnMarker.row);
612+
return {
613+
x: col * tileSize + (tileSize - hero.width) * 0.5,
614+
y: (row + 1) * tileSize - hero.height,
615+
};
616+
}
617+
}
618+
619+
return null;
620+
}
621+
622+
function normalizeTilesetSource(source) {
623+
if (!source || typeof source !== 'object') {
624+
return null;
625+
}
626+
627+
if (source.kind === 'atlas' || ('x' in source && 'y' in source)) {
628+
return {
629+
x: Number(source.x) || 0,
630+
y: Number(source.y) || 0,
631+
w: Number(source.width ?? source.w) || 0,
632+
h: Number(source.height ?? source.h) || 0,
633+
};
634+
}
635+
636+
return null;
637+
}
Lines changed: 23 additions & 4 deletions
Loading
Lines changed: 15 additions & 8 deletions
Loading
Lines changed: 14 additions & 11 deletions
Loading
872 Bytes
Loading
-306 Bytes
Loading

0 commit comments

Comments
 (0)