Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 116 additions & 15 deletions flixel/tile/FlxBaseTilemap.hx
Original file line number Diff line number Diff line change
Expand Up @@ -953,38 +953,139 @@ abstract class FlxBaseTilemap<Tile:FlxObject> extends FlxObject
loadMapHelper(tileGraphic, tileWidth, tileHeight, autoTile, startingIndex, drawIndex, collideIndex);
return this;
}

/**
* Load the tilemap with image data and a tile graphic.
* Black pixels are flagged as 'solid' by default, non-black pixels are set as non-colliding. Black pixels must be PURE BLACK.
* @param mapGraphic The image you want to use as a source of map data, where each pixel is a tile (or more than one tile if you change Scale's default value). Preferably black and white.
* @param invert Load white pixels as solid instead.
* @param scale Default is 1. Scale of 2 means each pixel forms a 2x2 block of tiles, and so on.
* @param colorMap An array of color values (alpha values are ignored) in the order they're intended to be assigned as indices
* Black pixels are flagged as 'solid' by default, non-black pixels are set as non-colliding.
* @param mapGraphic The image you want to use as a source of map data, where each
* pixel is a tile or chunk of tiles.
* @param whiteIsSolid Whether to load white pixels as solid and black and empty
* @param scale Default is 1. `scale` of 2 means each pixel forms a 2x2 block of tiles, and so on.
* @param colorMap An array of color values (ignores alpha) in the
* order they're intended to be assigned as indices
* @param tileGraphic All the tiles you want to use, arranged in a strip corresponding to the numbers in MapData.
* @param tileWidth The width of your tiles (e.g. 8) - defaults to height of the tile graphic if unspecified.
* @param tileHeight The height of your tiles (e.g. 8) - defaults to width if unspecified.
* @param autoTile Whether to load the map using an automatic tile placement algorithm (requires 16 tiles!).
* Setting this to either AUTO or ALT will override any values you put for StartingIndex, DrawIndex, or CollideIndex.
* Setting this to either `AUTO` or `ALT` will override any values you
* put for `startingIndex`, `drawIndex`, or `collideIndex`.
* @param startingIndex Used to sort of insert empty tiles in front of the provided graphic.
* Default is 0, usually safest ot leave it at that. Ignored if AutoTile is set.
* Default is 0, usually safest ot leave it at that. Ignored if `autoTile` is set.
* @param drawIndex Initializes all tile objects equal to and after this index as visible.
* Default value is 1. Ignored if AutoTile is set.
* Default value is 1. Ignored if `autoTile` is set.
* @param collideIndex Initializes all tile objects equal to and after this index as allowCollisions = ANY.
* Default value is 1. Ignored if AutoTile is set.
* Can override and customize per-tile-type collision behavior using setTileProperties().
* Default value is 1. Ignored if `autoTile` is set.
* Can override and customize per-tile-type collision behavior using `setTileProperties()`.
* @return A reference to this instance of FlxTilemap, for chaining as usual :)
* @since 4.1.0
*/
public function loadMapFromGraphic(mapGraphic:FlxGraphicAsset, invert = false, scale = 1, ?colorMap:Array<FlxColor>,
@:deprecated("loadMapFromGraphic with both bitmap and colorMap is deprecated, use a different overload of loadMapFromGraphic")
overload public inline extern function loadMapFromGraphic(mapGraphic:FlxGraphicAsset, whiteIsSolid:Bool, scale:Int, colorMap:Null<Array<FlxColor>>,
tileGraphic:FlxTilemapGraphicAsset, tileWidth = 0, tileHeight = 0, ?autoTile:FlxTilemapAutoTiling,
startingIndex = 0, drawIndex = 1, collideIndex = 1)
{
var mapBitmap:BitmapData = FlxAssets.resolveBitmapData(mapGraphic);
var mapData:String = FlxStringUtil.bitmapToCSV(mapBitmap, invert, scale, colorMap);
final mapData = if (colorMap == null)
FlxStringUtil.imageToCSV(mapGraphic, whiteIsSolid, scale);
else
FlxStringUtil.imageToCSV(mapGraphic, scale, colorMap);

return loadMapFromCSV(mapData, tileGraphic, tileWidth, tileHeight, autoTile, startingIndex, drawIndex, collideIndex);
}


/**
* Load the tilemap with image data and a tile graphic.
* Black pixels are flagged as 'solid' by default, non-black pixels are set as non-colliding.
* @param mapGraphic The image you want to use as a source of map data, where each
* pixel is a tile or chunk of tiles.
* @param scale Default is 1. `scale` of 2 means each pixel forms a 2x2 block of tiles, and so on.
* @param colorMap An array of rb color values (ignores alpha) in the
* order they're intended to be assigned as indices
* @param tileGraphic All the tiles you want to use, arranged in a strip corresponding to the numbers in MapData.
* @param tileWidth The width of your tiles (e.g. 8) - defaults to height of the tile graphic if unspecified.
* @param tileHeight The height of your tiles (e.g. 8) - defaults to width if unspecified.
* @param autoTile Whether to load the map using an automatic tile placement algorithm (requires 16 tiles!).
* Setting this to either `AUTO` or `ALT` will override any values you
* put for `startingIndex`, `drawIndex`, or `collideIndex`.
* @param startingIndex Used to sort of insert empty tiles in front of the provided graphic.
* Default is 0, usually safest ot leave it at that. Ignored if `autoTile` is set.
* @param drawIndex Initializes all tile objects equal to and after this index as visible.
* Default value is 1. Ignored if `autoTile` is set.
* @param collideIndex Initializes all tile objects equal to and after this index as allowCollisions = ANY.
* Default value is 1. Ignored if `autoTile` is set.
* Can override and customize per-tile-type collision behavior using `setTileProperties()`.
* @return A reference to this instance of FlxTilemap, for chaining as usual :)
* @since 6.2.0
*/
overload public inline extern function loadMapFromGraphic(mapGraphic:FlxGraphicAsset, scale = 1, colorMap:Array<FlxColor>,
tileGraphic:FlxTilemapGraphicAsset, tileWidth = 0, tileHeight = 0, ?autoTile:FlxTilemapAutoTiling,
startingIndex = 0, drawIndex = 1, collideIndex = 1)
{
final mapData:String = FlxStringUtil.imageToCSV(mapGraphic, scale, colorMap);
return loadMapFromCSV(mapData, tileGraphic, tileWidth, tileHeight, autoTile, startingIndex, drawIndex, collideIndex);
}

/**
* Load the tilemap with image data and a tile graphic.
* Black pixels are flagged as 'solid' by default, non-black pixels are set as non-colliding.
* @param mapGraphic The image you want to use as a source of map data, where each
* pixel is a tile or chunk of tiles.
* @param scale Default is 1. `scale` of 2 means each pixel forms a 2x2 block of tiles, and so on.
* @param colorMap An array of rgba color values in the order they're intended to be assigned as indices
* @param tileGraphic All the tiles you want to use, arranged in a strip corresponding to the numbers in MapData.
* @param tileWidth The width of your tiles (e.g. 8) - defaults to height of the tile graphic if unspecified.
* @param tileHeight The height of your tiles (e.g. 8) - defaults to width if unspecified.
* @param autoTile Whether to load the map using an automatic tile placement algorithm (requires 16 tiles!).
* Setting this to either `AUTO` or `ALT` will override any values you
* put for `startingIndex`, `drawIndex`, or `collideIndex`.
* @param startingIndex Used to sort of insert empty tiles in front of the provided graphic.
* Default is 0, usually safest ot leave it at that. Ignored if `autoTile` is set.
* @param drawIndex Initializes all tile objects equal to and after this index as visible.
* Default value is 1. Ignored if `autoTile` is set.
* @param collideIndex Initializes all tile objects equal to and after this index as allowCollisions = ANY.
* Default value is 1. Ignored if `autoTile` is set.
* Can override and customize per-tile-type collision behavior using `setTileProperties()`.
* @return A reference to this instance of FlxTilemap, for chaining as usual :)
* @since 6.2.0
*/
public function loadMap32FromGraphic(mapGraphic:FlxGraphicAsset, scale = 1, colorMap:Array<FlxColor>,
tileGraphic:FlxTilemapGraphicAsset, tileWidth = 0, tileHeight = 0, ?autoTile:FlxTilemapAutoTiling,
startingIndex = 0, drawIndex = 1, collideIndex = 1)
{
final mapData:String = FlxStringUtil.image32ToCSV(mapGraphic, scale, colorMap);
return loadMapFromCSV(mapData, tileGraphic, tileWidth, tileHeight, autoTile, startingIndex, drawIndex, collideIndex);
}

/**
* Load the tilemap with image data and a tile graphic.
* Black pixels are flagged as 'solid' by default, non-black pixels are set as non-colliding.
* @param mapGraphic The image you want to use as a source of map data, where each
* pixel is a tile or chunk of tiles
* @param whiteIsSolid Whether to load white pixels as solid and black and empty
* @param scale Default is 1. `scale` of 2 means each pixel forms a 2x2 block of tiles, and so on
* @param tileGraphic All the tiles you want to use, arranged in a strip corresponding to the numbers in MapData
* @param tileWidth The width of your tiles (e.g. 8) - defaults to height of the tile graphic if unspecified
* @param tileHeight The height of your tiles (e.g. 8) - defaults to width if unspecified
* @param autoTile Whether to load the map using an automatic tile placement algorithm (requires 16 tiles!).
* Setting this to either `AUTO` or `ALT` will override any values you
* put for `startingIndex`, `drawIndex`, or `collideIndex`
* @param startingIndex Used to sort of insert empty tiles in front of the provided graphic.
* Default is 0, usually safest ot leave it at that. Ignored if `autoTile` is set
* @param drawIndex Initializes all tile objects equal to and after this index as visible.
* Default value is 1. Ignored if `autoTile` is set
* @param collideIndex Initializes all tile objects equal to and after this index as allowCollisions = ANY.
* Default value is 1. Ignored if `autoTile` is set.
* Can override and customize per-tile-type collision behavior using `setTileProperties()`
* @return A reference to this instance of FlxTilemap, for chaining as usual :)
* @since 6.2.0
*/
overload public inline extern function loadMapFromGraphic(mapGraphic:FlxGraphicAsset, whiteIsSolid = false, scale = 1,
tileGraphic:FlxTilemapGraphicAsset, tileWidth = 0, tileHeight = 0, ?autoTile:FlxTilemapAutoTiling,
startingIndex = 0, drawIndex = 1, collideIndex = 1)
{
final mapData:String = FlxStringUtil.imageToCSV(mapGraphic, whiteIsSolid, scale);
return loadMapFromCSV(mapData, tileGraphic, tileWidth, tileHeight, autoTile, startingIndex, drawIndex, collideIndex);
}

function loadMapHelper(tileGraphic:FlxTilemapGraphicAsset, tileWidth = 0, tileHeight = 0, ?autoTile:FlxTilemapAutoTiling,
startingIndex = 0, drawIndex = 1, collideIndex = 1)
{
Expand Down
109 changes: 109 additions & 0 deletions flixel/util/FlxArrayUtil.hx
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,115 @@ class FlxArrayUtil
result.push(element);
return result;
}

/**
* For each nested array, duplicates each item the specifed `amount`, and then duplicates the
* arrays themselves.
*
* For example:
* ```haxe
* final arr =
* [
* [0, 2, 6],
* [1, 3, 7],
* [0, 0, 0]
* ];
* trace(FlxArrayUtil.scale(arr, 2, 3).join("\n"));
* // output:
* // 0,0,2,2,6,6
* // 0,0,2,2,6,6
* // 1,1,3,3,7,7
* // 1,1,3,3,7,7
* // 0,0,0,0,0,0
* // 0,0,0,0,0,0
* ```
*
* **NOTE:** Each added array is a unique instance, unlike the following, which will contain
* the same array instances:
* ```haxe
* FlxArrayUtil.scale(array.map((subArray)->FlxArrayUtil.scale(subArray, amount)), amount);
* ```
*
* @param data The array to be scaled
* @param amount The amount to duplicate each array and sub-array item
*
* @since 6.2.0
*/
overload public static inline extern function scale<T>(data:Array<Array<T>>, amount:Int):Array<Array<T>>
{
return scale(data, amount, amount);
}

/**
* For each nested array, duplicates each item by the specifed `subAmount`, and then duplicates
* the arrays by the specified `amount`.
*
* For example:
* ```haxe
* final arr =
* [
* [0, 2, 6],
* [1, 3, 7],
* [0, 0, 0]
* ];
* trace(FlxArrayUtil.scale(arr, 3, 2).join("\n"));
* // outputs:
* // 0,0,0,2,2,2,6,6,6
* // 0,0,0,2,2,2,6,6,6
* // 1,1,1,3,3,3,7,7,7
* // 1,1,1,3,3,3,7,7,7
* // 0,0,0,0,0,0,0,0,0
* // 0,0,0,0,0,0,0,0,0
* ```
* @since 6.2.0
*
* **NOTE:** Each added array is a unique instance, unlike the following, which will contain
* the same array instances:
* ```haxe
* FlxArrayUtil.scale(array.map((subArray)->FlxArrayUtil.scale(subArray, subAmount)), amount);
* ```
*
* @param data The array to be scaled
* @param subAmount The amount to duplicate each sub-array item
* @param amount The amount to duplicate each array
*
* @since 6.2.0
*/
overload public static inline extern function scale<T>(data:Array<Array<T>>, subAmount:Int, amount:Int):Array<Array<T>>
{
return scale2dHelper(data, subAmount, amount);
}

static function scale2dHelper<T>(data:Array<Array<T>>, subAmount:Int, amount:Int):Array<Array<T>>
{
final result:Array<Array<T>> = [];
for (row in data)
{
final scaledRow = scale(row, subAmount);
for (s in 0...amount)
result.push(s == 0 ? scaledRow : scaledRow.copy());
}
return result;
}

/**
* Takes an array and turns every duplicates item the specified `amount`.
* For example `scale([0, 9, 5], 3)` becomes `[0, 0, 0, 9, 9, 9, 5, 5, 5]`
*
* **NOTE:** Duplicated items will be the same instance, even if the data is an array of arrays
*
* @since 6.2.0
*/
overload public static inline extern function scale<T>(data:Array<T>, amount:Int):Array<T>
{
final result:Array<T> = [];
for (value in data)
{
for (s in 0...amount)
result.push(value);
}
return result;
}

/**
* Compares the contents with `==` to see if the two arrays are the same.
Expand Down
65 changes: 65 additions & 0 deletions flixel/util/FlxColor.hx
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,71 @@ abstract FlxColor(Int) from Int from UInt to Int to UInt
{
return FlxColor.fromRGB(lhs.red - rhs.red, lhs.green - rhs.green, lhs.blue - rhs.blue);
}

/**
* Returns the sum of the absolute differences of each channel between this and the specified color.
* For instance `FlxColor.RED.getDistance(0xFFf80080)` is `135`, or `(0xff - 0xf8) + (0x80 - 0x00)`
*
* @since 6.2.0
*/
public function getDistance(color:FlxColor)
{
inline function abs(n:Int):Int
{
return n < 0 ? -n : n;
}

return abs(color.red - red)
+ abs(color.green - green)
+ abs(color.blue - blue)
+ abs(color.alpha - alpha);
}

/**
* Searches the list of colors and returns the one whos rgba components are closets to this color.
* If colors is empty, the result is `null`
*
* @since 6.2.0
*/
overload public inline extern function nearest(colors:Array<FlxColor>):Null<FlxColor>
{
return getNearest(this, colors.iterator());
}

/**
* Searches the list of colors and returns the one whos rgba components are closets to this color.
* If colors is empty, the result is `null`
*
* @since 6.2.0
*/
overload public inline extern function nearest(colors:Iterator<FlxColor>):Null<FlxColor>
{
return getNearest(this, colors);
}

static function getNearest(target:FlxColor, colors:Iterator<FlxColor>):Null<FlxColor>
{
var closest:Null<FlxColor> = null;
var closestDiff = -1;

for (color in colors)
{
if (color == target)
{
closest = target;
break;
}

final diff = color.getDistance(target);
if (closest == null || diff < closestDiff)
{
closest = color;
closestDiff = diff;
}
}

return closest;
}

/**
* Returns a Complementary Color Harmony of this color.
Expand Down
Loading