Skip to content

Commit

Permalink
added spacing and borders support for combine tiles methods. fixes is…
Browse files Browse the repository at this point in the history
  • Loading branch information
Beeblerox authored and Aurel300 committed Apr 17, 2018
1 parent a3f720f commit 12a69b1
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 73 deletions.
99 changes: 37 additions & 62 deletions flixel/graphics/frames/FlxTileFrames.hx
Expand Up @@ -349,60 +349,16 @@ class FlxTileFrames extends FlxFramesCollection
*
* sprite.frames = combinedFrames;
*/
public static function combineTileSets(bitmaps:Array<BitmapData>, tileSize:FlxPoint):FlxTileFrames
public static function combineTileSets(bitmaps:Array<BitmapData>, tileSize:FlxPoint, ?spacing:FlxPoint, ?border:FlxPoint):FlxTileFrames
{
// we need to calculate the size of result bitmap first
var totalArea:Int = 0;
var rows:Int = 0;
var cols:Int = 0;

for (bitmap in bitmaps)
{
cols = Std.int(bitmap.width / tileSize.x);
rows = Std.int(bitmap.height / tileSize.y);
totalArea += Std.int(cols * tileSize.x * rows * tileSize.y);
}

var side:Float = Math.sqrt(totalArea);
cols = Std.int(side / tileSize.x);
rows = Math.ceil(totalArea / (cols * tileSize.x * tileSize.y));
var width:Int = Std.int(cols * tileSize.x);
var height:Int = Std.int(rows * tileSize.y);

// now we'll create result atlas and will blit every tile on it.
var combined:BitmapData = new BitmapData(width, height, true, FlxColor.TRANSPARENT);
var graphic:FlxGraphic = FlxG.bitmap.add(combined);
var result:FlxTileFrames = new FlxTileFrames(graphic);

result.region = FlxRect.get(0, 0, width, height);
result.atlasFrame = null;
result.tileSize = FlxPoint.get(tileSize.x, tileSize.y);
result.tileSpacing = FlxPoint.get(0, 0);
result.numCols = cols;
result.numRows = rows;

var frames:FlxTileFrames;
var point:Point = new Point(0, 0);
var framesCollections:Array<FlxTileFrames> = [];

for (bitmap in bitmaps)
{
frames = FlxTileFrames.fromRectangle(bitmap, tileSize);

for (frame in frames.frames)
{
frame.paint(combined, point, true);
result.addAtlasFrame(FlxRect.get(point.x, point.y, tileSize.x, tileSize.y), FlxPoint.get(tileSize.x, tileSize.y), FlxPoint.get(0, 0));
point.x += tileSize.x;

if (point.x >= combined.width)
{
point.x = 0;
point.y += tileSize.y;
}
}
framesCollections.push(FlxTileFrames.fromRectangle(bitmap, tileSize));
}

return result;
return combineTileFrames(framesCollections, spacing, border);
}

/**
Expand All @@ -419,7 +375,7 @@ class FlxTileFrames extends FlxFramesCollection
*
* sprite.frames = combinedFrames;
*/
public static function combineTileFrames(tileframes:Array<FlxTileFrames>):FlxTileFrames
public static function combineTileFrames(tileframes:Array<FlxTileFrames>, ?spacing:FlxPoint, ?border:FlxPoint):FlxTileFrames
{
// we need to calculate the size of result bitmap first
var totalArea:Int = 0;
Expand All @@ -429,48 +385,67 @@ class FlxTileFrames extends FlxFramesCollection
var tileWidth:Int = Std.int(tileframes[0].frames[0].sourceSize.x);
var tileHeight:Int = Std.int(tileframes[0].frames[0].sourceSize.y);

var spaceX:Int = 0;
var spaceY:Int = 0;

if (spacing != null)
{
spaceX = Std.int(spacing.x);
spaceY = Std.int(spacing.y);
}

var borderX:Int = 0;
var borderY:Int = 0;

if (border != null)
{
borderX = Std.int(border.x);
borderY = Std.int(border.y);
}

for (collection in tileframes)
{
cols = collection.numCols;
rows = collection.numRows;
totalArea += Std.int(cols * tileWidth * rows * tileHeight);
totalArea += Std.int(cols * (tileWidth + 2 * borderX) * rows * (tileHeight + 2 * borderY));
}

var side:Float = Math.sqrt(totalArea);
cols = Std.int(side / tileWidth);
rows = Math.ceil(totalArea / (cols * tileWidth * tileHeight));
var width:Int = Std.int(cols * tileWidth);
var height:Int = Std.int(rows * tileHeight);
var width:Int = Std.int(cols * tileWidth) + (cols - 1) * spaceX;
var height:Int = Std.int(rows * tileHeight) + (rows - 1) * spaceY;

// now we'll create result atlas and will blit every tile on it.
var combined:BitmapData = new BitmapData(width, height, true, FlxColor.TRANSPARENT);
var graphic:FlxGraphic = FlxG.bitmap.add(combined);
var result:FlxTileFrames = new FlxTileFrames(graphic);
var point:Point = new Point(0, 0);
var destPoint:Point = new Point(borderX, borderY);

result.region = FlxRect.get(0, 0, width, height);
result.atlasFrame = null;
result.tileSize = FlxPoint.get(tileWidth, tileHeight);
result.tileSpacing = FlxPoint.get(0, 0);
result.tileSpacing = FlxPoint.get(spaceX, spaceY);
result.numCols = cols;
result.numRows = rows;

// paint frames on result canvas with spaces between frames
for (collection in tileframes)
{
for (frame in collection.frames)
{
frame.paint(combined, point, true);
result.addAtlasFrame(FlxRect.get(point.x, point.y, tileWidth, tileHeight), FlxPoint.get(tileWidth, tileHeight), FlxPoint.get(0, 0));
point.x += tileWidth;
frame.paint(combined, destPoint, true);
result.addAtlasFrame(FlxRect.get(destPoint.x, destPoint.y, tileWidth, tileHeight), FlxPoint.get(tileWidth, tileHeight), FlxPoint.get(0, 0));
destPoint.x += tileWidth + 2 * borderX + spaceX;

if (point.x >= combined.width)
if (destPoint.x >= combined.width - borderX)
{
point.x = 0;
point.y += tileHeight;
destPoint.x = borderX;
destPoint.y += tileHeight + 2 * borderY + spaceY;
}
}
}

// and copy pixels around frames
FlxBitmapDataUtil.copyBorderPixels(combined, tileWidth, tileHeight, spaceX, spaceY, borderX, borderY, cols, rows);
return result;
}

Expand Down
48 changes: 37 additions & 11 deletions flixel/util/FlxBitmapDataUtil.hx
Expand Up @@ -382,52 +382,78 @@ class FlxBitmapDataUtil
result.copyPixels(bitmapData, tempRect, tempPoint);
}
}
result.unlock();

// copy borders
tempPoint.setTo(0, 0);
tempRect.setTo(0, 0, 1, result.height);
for (i in 0...numHorizontalFrames)
copyBorderPixels(result, frameWidth, frameHeight, spaceX, spaceY, borderX, borderY, numHorizontalFrames, numVerticalFrames);
return result;
}

/**
* Helper method for copying border pixels around tiles.
* It modifies provided image, and assumes that there are spaces between tile images already.
*
* @param bitmapData image with spaces between tiles to fill with border pixels
* @param frameWidth tile width
* @param frameHeight tile heigth
* @param spaceX horizontal spacing between tiles
* @param spaceY vertical spacing between tiles
* @param borderX how many times to copy border of tiles on horizontal axis.
* @param borderY how many times to copy border of tiles on vertical axis.
* @param horizontalFrames how many columns of tiles on provided image.
* @param verticalFrames how many rows of tiles on provided image.
*
* @return Modified spritesheet with copied pixels around tile images.
*/
public static function copyBorderPixels(bitmapData:BitmapData, frameWidth:Int, frameHeight:Int, spaceX:Int, spaceY:Int, borderX:Int, borderY:Int, horizontalFrames:Int, verticalFrames:Int):BitmapData
{
// copy borders
var tempRect:Rectangle = new Rectangle(0, 0, 1, bitmapData.height);
var tempPoint:Point = new Point();
bitmapData.lock();

for (i in 0...horizontalFrames)
{
tempRect.x = i * (frameWidth + 2 * borderX + spaceX) + borderX;

for (j in 0...borderX)
{
tempPoint.x = tempRect.x - j - 1;
result.copyPixels(result, tempRect, tempPoint);
bitmapData.copyPixels(bitmapData, tempRect, tempPoint);
}

tempRect.x += frameWidth - 1;

for (j in 0...borderX)
{
tempPoint.x = tempRect.x + j + 1;
result.copyPixels(result, tempRect, tempPoint);
bitmapData.copyPixels(bitmapData, tempRect, tempPoint);
}
}

tempPoint.setTo(0, 0);
tempRect.setTo(0, 0, result.width, 1);
for (i in 0...numVerticalFrames)
tempRect.setTo(0, 0, bitmapData.width, 1);
for (i in 0...verticalFrames)
{
tempRect.y = i * (frameHeight + 2 * borderY + spaceY) + borderY;

for (j in 0...borderY)
{
tempPoint.y = tempRect.y - j - 1;
result.copyPixels(result, tempRect, tempPoint);
bitmapData.copyPixels(bitmapData, tempRect, tempPoint);
}

tempRect.y += frameHeight - 1;

for (j in 0...borderY)
{
tempPoint.y = tempRect.y + j + 1;
result.copyPixels(result, tempRect, tempPoint);
bitmapData.copyPixels(bitmapData, tempRect, tempPoint);
}
}

result.unlock();
return result;
bitmapData.unlock();
return bitmapData;
}

/**
Expand Down

0 comments on commit 12a69b1

Please sign in to comment.