UNPKG

create-phaser-app

Version:

A boiler plate to start your phaser app with webpack4, babel7+ and Phaser 3

245 lines (210 loc) 6.02 kB
console.log('Processing Levels'); //TODO: /* - Squish images - update the processor to ignore layerr that are 'raw input' by allowing the user to mark them as irrelevant in Tiled - Same thing with tilemaps! Mark the input tilemap as irrelevant - Document this and teach users how to use the level processor */ import fs from 'fs'; import path from 'path'; import chalk from 'chalk'; import globby from 'globby'; import _ from 'lodash'; import { extrudeTilesetToImage } from 'tile-extruder'; import { ROOT_PATH } from '../paths'; import addOcclusionLayers from './add-occlusion-layers'; import { BASE_HEIGHT, BASE_WIDTH, COLOR, INPUT_ONLY_PROP, MARGIN, PROCESSED_FOLDER, RAW_FOLDER, SPACING, TEMP_FOLDER } from './consts'; import { moveLayerImages, templateImageImportFile } from './level-image-processing'; const LEVELS_INPUT_PATH = path.posix .resolve(__dirname, `../../src/assets/levels/${RAW_FOLDER}/**/*.json`) .replace(/\\/g, '/'); async function getLevelsPaths() { let t = await globby(LEVELS_INPUT_PATH); return t; } async function extrudeTileset({ input, output, width, height, spacing, margin }) { console.table({ input, output, width: width || BASE_WIDTH, height: height || BASE_HEIGHT, margin: margin || MARGIN, spacing: spacing || SPACING }); let extrudedTileset; try { extrudedTileset = await extrudeTilesetToImage( width || BASE_WIDTH, height || BASE_HEIGHT, input, output, { margin: margin || MARGIN, spacing: spacing || SPACING, color: COLOR } ); } catch (err) { console.log(chalk.red(`Error extruding: ${input}`)); console.log(chalk.red(err)); } return extrudedTileset; } function getOutputPath(inputPath) { return path.resolve( inputPath.replace(`${RAW_FOLDER}`, `${PROCESSED_FOLDER}`) ); } function withoutInputLayers(layer) { if ( layer.properties && _.find(layer.properties, { name: INPUT_ONLY_PROP }) && _.find(layer.properties, { name: INPUT_ONLY_PROP }).value === true ) { return false; } return true; } async function rewriteLevel(inputPath, index) { inputPath = path.resolve(inputPath); const outputPath = getOutputPath(inputPath); const level = JSON.parse(fs.readFileSync(inputPath, 'utf-8')); const { tilesets, layers } = level; const thisDir = path.dirname(inputPath); //gathers external tilesets for embedding if (!tilesets) { //there's not any tilesets return; } let gid = 1; function tileSetToFullyEmbeddedTileset(tileset, index) { //the user embedded the tilemap, so just.. give it back! if (!tileset.source) { return tileset; } // the user has NOT embedded the tileset, so we are // going to go get it and the 'output' // in the processed folder, that shall be embedded let _jsonSource = tileset.source.replace('.tsx', '.json'); let externalTileset = fs.readFileSync( path.resolve(__dirname, thisDir, _jsonSource) ); return JSON.parse(externalTileset); } function tilesetToCorrectedTileset(tileset, index) { const { image, tileheight, tilewidth, spacing, margin, columns, imageheight, imagewidth, type } = tileset; const levelImageInputPath = path.resolve(__dirname, thisDir, image); const levelImageOutputPath = getOutputPath(levelImageInputPath); // TODO: the underplaying tileset extruder is NOT async! // if I want to do minification and things like that // I'll likely need to fix this. let extrudedTileset = extrudeTileset({ input: levelImageInputPath, output: levelImageOutputPath, width: tilewidth, height: tileheight, spacing: spacing, margin: margin }); const rows = Math.round(imageheight / (tileheight + spacing)); const currentGid = gid; gid = gid + tileset.tilecount; return { ...tileset, ...{ margin: margin + 1, spacing: spacing + 2, imageheight: rows * (tileheight + spacing + 2), imagewidth: columns * (tilewidth + spacing + 2), firstgid: currentGid } }; } const fullyEmbeddedTilesets = tilesets.map(tileSetToFullyEmbeddedTileset); const correctedTilesets = fullyEmbeddedTilesets.map( tilesetToCorrectedTileset ); const updatedLayers = layers.filter(withoutInputLayers); let processedLevel = { ...level, ...{ layers: updatedLayers, tilesets: correctedTilesets } }; //Build occlusion layers. processedLevel = addOcclusionLayers(processedLevel); //Move images to build folder and template images.js // TODO: maybe move all the images at one time by putting them in a queue? let movedImages = await moveLayerImages( processedLevel, thisDir, getOutputPath(thisDir) ); templateImageImportFile(processedLevel, thisDir, getOutputPath(thisDir)); //write the completed Json! const newLevelFileContents = JSON.stringify(processedLevel); let rewrittenLevel = fs.writeFileSync(outputPath, newLevelFileContents); return await Promise.all([movedImages, rewrittenLevel]); } async function processLevels(data) { var levelPaths = await getLevelsPaths(); console.log(chalk.green(`Found levels:`)); levelPaths.forEach(l => { console.log(chalk.white(`📁 ${l}`)); }); return levelPaths.map(rewriteLevel); } function getDirectories(srcpath) { return fs .readdirSync(srcpath) .map(file => path.join(srcpath, file)) .filter(path => fs.statSync(path).isDirectory()); } function prepOutputDirectory() { const rawDirectories = getDirectories( path.resolve(__dirname, `../../src/assets/levels/${RAW_FOLDER}`) ); rawDirectories.forEach(dir => { const outDir = getOutputPath(dir); if (!fs.existsSync(outDir)) { fs.mkdirSync(outDir); } }); } prepOutputDirectory(); processLevels().then(() => { console.log(chalk.green('All Levels Processed')); });