Hacking Flixel AutoTile to support over 16 tiles.
AKA: Multiple auto tiling sets on same screen.
Saving Original Function as I hack away at it:
In FlxTileMap:
/**
* An internal function used by the binary auto-tilers.
*
* @param Index The index of the tile you want to analyze.
*/
protected function autoTile(Index:uint):void
{
if(_data[Index] == 0)
return;
_data[Index] = 0;
if((Index-widthInTiles < 0) || (_data[Index-widthInTiles] > 0)) //UP (JM: Very top of map, or tile above Index tile)
_data[Index] += 1;
if((Index%widthInTiles >= widthInTiles-1) || (_data[Index+1] > 0)) //RIGHT
_data[Index] += 2;
if((Index+widthInTiles >= totalTiles) || (_data[Index+widthInTiles] > 0)) //DOWN
_data[Index] += 4;
if((Index%widthInTiles <= 0) || (_data[Index-1] > 0)) //LEFT
_data[Index] += 8;
if((auto == ALT) && (_data[Index] == 15)) //The alternate algo checks for interior corners
{
if((Index%widthInTiles > 0) && (Index+widthInTiles < totalTiles) && (_data[Index+widthInTiles-1] <= 0))
_data[Index] = 1; //BOTTOM LEFT OPEN
if((Index%widthInTiles > 0) && (Index-widthInTiles >= 0) && (_data[Index-widthInTiles-1] <= 0))
_data[Index] = 2; //TOP LEFT OPEN
if((Index%widthInTiles < widthInTiles-1) && (Index-widthInTiles >= 0) && (_data[Index-widthInTiles+1] <= 0))
_data[Index] = 4; //TOP RIGHT OPEN
if((Index%widthInTiles < widthInTiles-1) && (Index+widthInTiles < totalTiles) && (_data[Index+widthInTiles+1] <= 0))
_data[Index] = 8; //BOTTOM RIGHT OPEN
}
_data[Index] += 1;
}
Created fast re-mapping function to test logic for re-mapping
indicies without the use of the slow "Math.floor"
private function indexToColumnNumberRemap(columnWidth:int):void
{
//In Flixel: When using auto-tiling, you have 16 tiles to choose from.
// Tiles 1 - 16. Represented in based zero here by 0 - 15
// If I want to edit Flixels: "autoTile" function in FlxTileMap, I will have to
// re-map a given tile-number to what tile-set it belongs to.
// this code attempts to do that re-map blazingly fast.
// faster than: Math.ceil( index / 15 ) - 1;
// or faster than: INV_15 = 1/15; Math.ceil( index * INV_15 ) - 1;
//
// [00][01][02][03][04][05][06][07][08][09][10][11][12][13][14][15] //USE TILE SET # 0; 0 - 15
// [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] //USE TILE SET # 1; 16- 31
// [32][33][34][35][36][37][38][39][40][41][42][43][44][45][46][47] //USE TILE SET # 2; 32- 47
// [48][49][50][51][52][53][54][55][56][57][58][59][60][61][62][63] //USE TILE SET # 3; 48- 63
// [64]
var inv_ColumnWidth :Number = 1 / columnWidth;
var inv_ColumnWidthPlus1:Number = 1 / (columnWidth + 1);
var shift:int;
var finalVal:int;
var I:int;
for (var i:int = 0; i < 100; i++)
{
shift = int( i * inv_ColumnWidth );
I = i + shift;
finalVal = int( I * inv_ColumnWidthPlus1);
trace(i + " finalVal==" + finalVal);
}
}
private function divTest_015():void
{
// Proof of concept function: Remap logic:
// [00][01][02][03][04][05][06][07][08][09][10][11][12][13][14][15] //USE TILE SET # 0; 0 - 15
// [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] //USE TILE SET # 1; 16- 31
// [32][33][34][35][36][37][38][39][40][41][42][43][44][45][46][47] //USE TILE SET # 2; 32- 47
// [48][49][50][51][52][53][54][55][56][57][58][59][60][61][62][63] //USE TILE SET # 3; 48- 63
// [64]
var I:int; //i shifted back one.
var d:int;
var m:int;
var r:int;
var finalVal:int;
for (var i:int = 0; i < 100; i++)
{
m = int( (i) / 16);
I = i + m;
finalVal = int( I / (16 + 1) ); //i divided by 17, rather than 16. Will shift off by one each cycle of 16,
trace(i + " m==" + m + " finalVal==" + finalVal);
}
}
As fun as that was... Remapping using:
Is a bit faster.
Here is my benchmark test:
private function remapBenchmarkTest(columnWidth:int):void
{
//In Flixel: When using auto-tiling, you have 16 tiles to choose from.
// Tiles 1 - 16. Represented in based zero here by 0 - 15
// If I want to edit Flixels: "autoTile" function in FlxTileMap, I will have to
// re-map a given tile-number to what tile-set it belongs to.
// this code attempts to do that re-map blazingly fast.
// faster than: Math.ceil( index / 15 ) - 1;
// or faster than: INV_15 = 1/15; Math.ceil( index * INV_15 ) - 1;
//
// update: actual calculation using floor;
// Math.ceil( (i + 1) / columnWidth) - 1);
//
// [00][01][02][03][04][05][06][07][08][09][10][11][12][13][14][15] //USE TILE SET # 0; 0 - 15
// [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] //USE TILE SET # 1; 16- 31
// [32][33][34][35][36][37][38][39][40][41][42][43][44][45][46][47] //USE TILE SET # 2; 32- 47
// [48][49][50][51][52][53][54][55][56][57][58][59][60][61][62][63] //USE TILE SET # 3; 48- 63
// [64]
var MAXTIMES:int = 9876543;
var inv_ColumnWidth :Number = 1 / columnWidth;
var inv_ColumnWidthPlus1:Number = 1 / (columnWidth + 1);
var shift:int;
var finalVal:int;
var I:int;
var t:int; //for timer.
t = getTimer();
var i:int;
for (i = 0; i < MAXTIMES; i++)
{
shift = int( i * inv_ColumnWidth );
I = i + shift;
finalVal = int( I * inv_ColumnWidthPlus1);
//if (finalVal != ( Math.ceil( (i + 1) / columnWidth) - 1) ) { throw new Error("HAY!!!"); }
//trace(i + " finalVal==" + finalVal);
}
t = getTimer() - t;
trace("time taken for optimized code:" + t);
t = getTimer();
for (i = 0; i < MAXTIMES; i++)
{
Math.ceil(i);
}
t = getTimer() - t;
trace("time taken for just using Math.ceil" + t);
t = getTimer();
for (i = 0; i < MAXTIMES; i++)
{
finalVal = Math.ceil( (i + 1) / columnWidth) - 1;
}
t = getTimer() - t;
trace("time taken for actual remap code using math.ceil" + t);
}
No comments:
Post a Comment