create script to pack and upack map data

This commit is contained in:
evanpelle
2024-08-21 08:06:36 -07:00
parent 8bd86d0384
commit d0f4f4d129
3 changed files with 116 additions and 65 deletions
-43
View File
@@ -1,43 +0,0 @@
import Jimp from 'jimp';
import * as $protobuf from 'protobufjs/minimal.js';
// import {TerrainTile} from '../generated/protos';
async function generateTerrainMap(imagePath, outputDir) {
const terrain = new TerrainTile()
try {
// const imageModule = await import(imagePath);
// const imageUrl = imageModule.default;
// const image = await Jimp.read(imageUrl);
// const {width, height} = image.bitmap;
// const map = new TerrainMap();
// map.TerrainTile
// image.scan(0, 0, width, height, function (x, y, idx) {
// const terrain = new TerrainTile();
// const red = this.bitmap.data[idx + 0];
// if (red > 100) {
// // terrain[x][y] = TerrainTypes.Land;
// }
// });
// return new TerrainMapImpl(terrain);
console.log('Terrain map generated successfully');
} catch (error) {
console.error('Error generating terrain map:', error);
}
}
// Usage
const imagePath = process.argv[2];
const outputDir = process.argv[3] || 'generated';
if (!imagePath) {
console.error('Usage: node TerrainMapGenerator.js <imagePath> [outputDir]');
process.exit(1);
}
generateTerrainMap(imagePath, outputDir).catch(console.error);
export {generateTerrainMap};
+116 -22
View File
@@ -1,27 +1,121 @@
import {Jimp as JimpType, JimpConstructors} from '@jimp/core';
import 'jimp';
import {TerrainMap, TerrainTile} from '../../generated/protos';
import PImage from 'pureimage';
import fs from 'fs/promises';
import path from 'path';
import {fileURLToPath} from 'url';
import {createReadStream, createWriteStream} from 'fs';
import zlib from 'zlib';
import {promisify} from 'util';
const deflateRaw = promisify(zlib.deflateRaw);
const inflateRaw = promisify(zlib.inflateRaw);
declare const Jimp: JimpType & JimpConstructors;
export async function loadTerrainMap(): Promise<TerrainMap> {
const imageModule = await import(`../../resources/maps/World.png`);
const imageUrl = imageModule.default;
const image = await Jimp.read(imageUrl)
const {width, height} = image.bitmap;
image.scan(0, 0, width, height, function (x: number, y: number, idx: number) {
const t: TerrainTile = new TerrainTile()
const red = this.bitmap.data[idx + 0];
if (red > 100) {
}
})
return new TerrainMap()
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
interface TerrainMap {
width: number;
height: number;
terrain: TerrainTile[][];
}
// loadTerrainMap()
interface TerrainTile {
isLand: boolean
}
export async function loadTerrainMap(): Promise<TerrainMap> {
try {
const imagePath = path.resolve(__dirname, '..', '..', 'resources', 'maps', 'World.png');
console.log('Attempting to load image from:', imagePath);
try {
await fs.access(imagePath);
} catch (error) {
throw new Error(`Image file not found at ${imagePath}. Please ensure the file exists.`);
}
const readStream = createReadStream(imagePath);
const img = await PImage.decodePNGFromStream(readStream);
console.log('Image loaded successfully');
console.log('Image dimensions:', img.width, 'x', img.height);
const terrainMap: TerrainMap = {
width: img.width,
height: img.height,
terrain: []
};
// Iterate through each pixel
for (let x = 0; x < img.width; x++) {
terrainMap.terrain[x] = [];
for (let y = 0; y < img.height; y++) {
const color = img.getPixelRGBA(x, y);
const red = (color >> 24) & 0xff;
// Extract the red channel (assuming it represents height)
const height = (color >> 24) & 0xff;
terrainMap.terrain[x][y] = {
isLand: red > 100
};
}
}
console.log('Terrain data extracted');
// Serialize the terrain data using MessagePack
const msg = JSON.stringify(terrainMap)
const compressedData = await deflateRaw(msg);
// Save the serialized data
const outputPath = path.join(__dirname, 'terrain_data.msgpack');
fs.writeFile(outputPath, compressedData);
console.log('Serialized terrain data saved to:', outputPath);
return terrainMap
} catch (error) {
console.error('Error loading or processing the terrain map:', error);
throw error;
}
}
// Test the function
loadTerrainMap().then(terrainData => {
console.log('Terrain data loaded');
console.log('Terrain data extracted');
}).catch(console.error);
console.log('Processing terrain map...');
async function loadAndDecodeTerrainData(): Promise<TerrainMap> {
try {
// Construct the path to the MessagePack file
const filePath = path.join(__dirname, 'terrain_data.msgpack');
// Read the file
const data = await fs.readFile(filePath);
const inflated = await inflateRaw(data)
const decodedData = JSON.parse(inflated.toString('utf-8')) as TerrainMap
console.log('Terrain data loaded and decoded successfully');
console.log('Dimensions:', decodedData.width, 'x', decodedData.height);
console.log('Sample height at (0,0):', decodedData.terrain[0][0]);
return decodedData;
} catch (error) {
console.error('Error loading or decoding the terrain data:', error);
throw error;
}
}
// Usage example
loadAndDecodeTerrainData()
.then(terrainData => {
// You can now use terrainData in your application
console.log('Terrain data ready for use');
})
.catch(console.error);
Binary file not shown.