topical media & game development
mobile-game-ch08-spriter-spriter.js / js
var fs = require('fs'),
util = require('util'),
Canvas = require('canvas'),
Image = Canvas.Image,
Futures = require('futures'),
Join = Futures.join;
var maxSpriteWidth = 2048;
function spriter(directory) {
var files = fs.readdirSync(directory),
rowData = {},
// Load all the images
join = loadImages(directory,files,rowData);
// Wait for the all images to load
join.when(function() {
// Get the dimensions of the output sprite map
var dimensions = calculateSize(rowData),
canvas = new Canvas(dimensions.width, dimensions.height);
// Draw the images to the canvas and return the JSON data
var jsonOutput = drawImages(rowData,canvas);
// Write out both the sprites.png and sprites.json files
fs.writeFileSync("mobile-game-ch08-spriter-sprites.png",canvas.toBuffer());
fs.writeFileSync("mobile-game-ch08-spriter-sprites.json",JSON.stringify(jsonOutput));
util.print("Wrote sprites.png and sprites.json\n");
});
}
function loadImages(directory,files,rowData) {
var fileRegex = /^(.*?)([0-9]+)\.[a-zA-Z]{3}/,"") + "/" + file;
rowData[rowName] = rowData[rowName] || [];
rowData[rowName].push([fileNum,img]);
}
})(files[i]);
}
return join;
}
function calculateSize(rowData) {
var maxWidth = 0,
totalHeight = 0;
for(var spriteName in rowData) {
// Order by ascending number
var row = rowData[spriteName],
firstImage = row[0][1],
width = firstImage.width * row.length,
rows = 1;
if(width > maxSpriteWidth) {
rows = Math.ceil(width / maxSpriteWidth);
width = maxSpriteWidth;
}
maxWidth = Math.max(width,maxWidth);
totalHeight += firstImage.height * rows;
}
return { width: maxWidth, height: totalHeight };
}
function drawImages(rowData,canvas) {
var ctx = canvas.getContext('2d'),
curY = 0,
jsonOutput = {};
for(var spriteName in rowData) {
// Order by ascending number
var row = rowData[spriteName].sort(function(a,b) { return a[0] - b[0]; }),
firstImage = row[0][1],
imageWidth = firstImage.width,
rowHeight = firstImage.height,
rowWidth = Math.min(imageWidth * row.length, maxSpriteWidth),
cols = Math.floor(rowWidth / imageWidth),
rows = Math.ceil(row.length / cols);
console.log(spriteName + " " + cols + " " + rows);
jsonOutput[spriteName] = { sx: 0, sy: curY, cols: cols,
tilew: imageWidth, tileh: rowHeight,
frames: row.length };
for(var i =0;i<rows;i++) {
for(var k=0;k<cols;k++) {
if(row[k+i*cols]) {
ctx.drawImage(row[k + i*cols ][1],k*imageWidth,curY);
}
}
curY += rowHeight;
}
}
return jsonOutput;
}
// Make the spriter method available
module.exports = spriter;
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.