我正在编写一个批处理脚本,使用TexturePacker的命令行工具生成精灵表。
for /f "delims=" %%i in ('dir /b sprites') do (
TexturePacker --format "json" --data "sheets/%%i.json" --sheet "sheets/%%i.png" "sprites/%%i"
)
到目前为止非常简单,但我想知道是否有可能从该工具生成[* .tps]文件。因此,如果有人想要检查导出的属性,他们可以通过TexturePackerGUI来完成。
答案 0 :(得分:1)
这是我用来在文件夹中构建所有.tps文件的bash脚本:
#!/bin/bash
for i in *.tps; do TexturePacker assets/texture_packer/$i; done
答案 1 :(得分:0)
此批处理脚本在文件夹中生成所有* .tps:
const topZero = 0;
const parent = i => ((i + 1) >>> 1) - 1;
const left = i => (i << 1) + 1;
const right = i => (i + 1) << 1;
class PriorityQueue {
constructor(comparator = (a, b) => a > b) {
this._heap = [];
this._comparator = comparator;
}
size() {
return this._heap.length;
}
isEmpty() {
return this.size() == 0;
}
peek() {
return this._heap[topZero];
}
push(...values) {
values.forEach(value => {
this._heap.push(value);
this._siftUp();
});
return this.size();
}
pop() {
const poppedValue = this.peek();
const bottom = this.size() - 1;
if (bottom > topZero) {
this._swap(topZero, bottom);
}
this._heap.pop();
this._siftDown();
return poppedValue;
}
replace(value) {
const replacedValue = this.peek();
this._heap[topZero] = value;
this._siftDown();
return replacedValue;
}
_greater(i, j) {
return this._comparator(this._heap[i], this._heap[j]);
}
_swap(i, j) {
[this._heap[i], this._heap[j]] = [this._heap[j], this._heap[i]];
}
_siftUp() {
let node = this.size() - 1;
while (node > topZero && this._greater(node, parent(node))) {
this._swap(node, parent(node));
node = parent(node);
}
}
_siftDown() {
let node = topZero;
while (
(left(node) < this.size() && this._greater(left(node), node)) ||
(right(node) < this.size() && this._greater(right(node), node))
) {
let maxChild = (right(node) < this.size() && this._greater(right(node), left(node))) ? right(node) : left(node);
this._swap(node, maxChild);
node = maxChild;
}
}
}
const rectangles = [{
rectID: "b22d",
"yTop": 0,
"yBottom": 60,
"leftX": -1,
"rightX": -1
},
{
rectID: "8938",
"yTop": 60,
"yBottom": 120,
"leftX": -1,
"rightX": -1
},
{
rectID: "e78a",
"yTop": 60,
"yBottom": 120,
"leftX": -1,
"rightX": -1
},
{
rectID: "81ed",
"yTop": 207,
"yBottom": 222,
"leftX": -1,
"rightX": -1
},
{
rectID: "b446",
"yTop": 207,
"yBottom": 222,
"leftX": -1,
"rightX": -1
},
{
rectID: "ebd3",
"yTop": 207,
"yBottom": 222,
"leftX": -1,
"rightX": -1
},
{
rectID: "2caf",
"yTop": 208,
"yBottom": 223,
"leftX": -1,
"rightX": -1
},
{
rectID: "e623",
"yTop": 227,
"yBottom": 242,
"leftX": -1,
"rightX": -1
},
{
rectID: "e6a3",
"yTop": 270,
"yBottom": 320,
"leftX": -1,
"rightX": -1
},
{
rectID: "e613",
"yTop": 272,
"yBottom": 460,
"leftX": -1,
"rightX": -1
},
{
rectID: "c2d1",
"yTop": 272,
"yBottom": 290,
"leftX": -1,
"rightX": -1
},
{
rectID: "e64d",
"yTop": 274,
"yBottom": 300,
"leftX": -1,
"rightX": -1
},
{
rectID: "b653",
"yTop": 276,
"yBottom": 310,
"leftX": -1,
"rightX": -1
},
{
rectID: "e323",
"yTop": 276,
"yBottom": 310,
"leftX": -1,
"rightX": -1
},
{
rectID: "fca3",
"yTop": 300,
"yBottom": 315,
"leftX": -1,
"rightX": -1
}
];
let eventQueue = new PriorityQueue((a, b) => {
if (a.y !== b.y) return a.y < b.y;
if (a.type !== b.type) return a.type > b.type;
return a.rectID > b.rectID;
})
let regionQueue = []; // FIFO
const EVENT_START = 0;
const EVENT_STOP = 1;
const queueAdd = (queue, toAdd, type, priority) => {
return queue.push(toAdd);
}
const queuePop = (queue) => {
return queue.pop();
}
const queueDestroy = (queue) => {
return queue = [];
}
const optimizeLeftAndRightXStartPointsForNormalizedRectangleAreaWithoutOverlapping = (rectArray, length, overlapLimit, containerWidth) => {
// fill the event queue with START and STOP events for each rectangle
for (let i = 0; i < length; i++) {
let startEvent = {
y: rectArray[i].yTop,
type: EVENT_START,
index: i
};
eventQueue.push(startEvent);
let stopEvent = {
y: rectArray[i].yBottom,
type: EVENT_STOP,
index: i
};
eventQueue.push(stopEvent);
}
while (eventQueue.size()) { // queueIsNotEmpty(eventQueue)
// search for the end of a region, while keeping track of the overlap in that region
let overlap = 0;
let maxOverlap = 0;
let event;
while (event = eventQueue.pop()) { // take from the event queue
queueAdd(regionQueue, event); // save in the region queue
if (event.type === 0) {
overlap++;
} else {
overlap--;
}
if (overlap === 0) { // reached the end of a region
break;
}
// if we have a new maximum for the overlap, update 'maxOverlap'
if (overlap > maxOverlap) {
maxOverlap = overlap;
}
}
// limit the overlap as specified by the function parameter
if (maxOverlap > overlapLimit) {
maxOverlap = overlapLimit;
}
// compute the width to be used for rectangles in this region
const width = parseInt(containerWidth / maxOverlap);
// create and initialize an array to keep track of which columns are in use
let usedColumns = new Array(maxOverlap);
for (let i = 0; i < maxOverlap; i++) {
if (usedColumns[i] == event.rectID) {
usedColumns[i] = -1;
break;
}
}
// process the region, computing left and right X values for each rectangle
while (event = queuePop(regionQueue)) {
if (event.type == 0) {
// find an available column for this rectangle, and assign the X values
for (let column = 0; column < maxOverlap; column++) {
if (usedColumns[column] < 0) {
usedColumns[column] = event.rectID;
rectArray[event.index].leftX = column * width;
rectArray[event.index].rightX = (column + 1) * width;
break;
}
}
} else {
// free the column that's being used for this rectangle
for (let i = 0; i < maxOverlap; i++)
if (usedColumns[i] == event.rectID) {
usedColumns[i] = -1;
break;
}
}
}
}
return rectArray;
}
const displayResults = (completedRectangleList) => {
const rectangleColors = ['cyan', 'magenta', 'green', 'yellow', 'orange']
completedRectangleList.forEach((rectangle, index) => {
if (rectangle.leftX > -1 && rectangle.rightX > -1) {
let newRectangle = document.createElement('div');
newRectangle.style.position = 'absolute';
newRectangle.style.height = rectangle.yBottom - rectangle.yTop + 'px';
newRectangle.style.top = rectangle.yTop + 'px';
newRectangle.style.left = parseInt(rectangle.leftX) + '%';
newRectangle.style.width = rectangle.rightX - rectangle.leftX + "%";
newRectangle.style.backgroundColor = rectangleColors[index % rectangleColors.length];
newRectangle.innerHTML = rectangle.rectID;
if (rectangle.isMax) {
newRectangle.innerHTML += '- more hidden';
}
document.body.appendChild(newRectangle);
}
})
}
let results = optimizeLeftAndRightXStartPointsForNormalizedRectangleAreaWithoutOverlapping(rectangles, (rectangles.length), 3, 100);
console.log('results ' + JSON.stringify(results));
displayResults(results);