Created
December 16, 2014 11:55
-
-
Save oscarcs/848fef0e2c16f0dd3201 to your computer and use it in GitHub Desktop.
Manage a grid of FlxTilemaps
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ; | |
import flixel.FlxG; | |
import flixel.tile.FlxTilemap; | |
import flixel.util.FlxPoint; | |
/** | |
* Class for management of an array of tilemaps. | |
*/ | |
class TilemapGrid | |
{ | |
/** | |
* Width in number of tilemaps. | |
*/ | |
public var width:Int; | |
/** | |
* Height in number of tilemaps. | |
*/ | |
public var height:Int; | |
/** | |
* Number of tiles across the whole grid. | |
*/ | |
public var widthInTiles:Int; | |
/** | |
* Number of tiles down the whole grid. | |
*/ | |
public var heightInTiles:Int; | |
private var imageData:Dynamic; | |
private var sizeOfTilemap:Int; | |
private var masterTileArray:Array<Int>; | |
/** | |
* Active status by index for tilemaps. | |
*/ | |
public var activeMap:Array<Bool>; | |
/** | |
* The actual array of tilemaps. | |
*/ | |
public var tilemapArray:Array<FlxTilemap>; | |
private var tileSize:Int = 16; | |
/** | |
* New TilemapGrid. | |
* @param w Width in tilemaps (not tiles!) | |
* @param h Height in tilemaps (not tiles!) | |
* @param SizeOfTilemap Width & height of each tilemap | |
* @param ImageData The image to use for tilemaps. | |
*/ | |
public function new(w:Int, h:Int, SizeOfTilemap:Int, ImageData:Dynamic) | |
{ | |
width = w; | |
height = h; | |
sizeOfTilemap = SizeOfTilemap; | |
imageData = ImageData; | |
widthInTiles = width * sizeOfTilemap; | |
heightInTiles = height * sizeOfTilemap; | |
masterTileArray = [for (i in 0...(widthInTiles * heightInTiles)) 0]; | |
activeMap = []; | |
for (i in 0...(width * height)) { activeMap[i] = false; } | |
tilemapArray = [for (i in 0...(width * height)) null]; | |
} | |
/** | |
* Set tile by point. | |
* @param tile_x | |
* @param tile_y | |
* @param value | |
*/ | |
public function setTile(tile_x:Int, tile_y:Int, value:Int) | |
{ | |
masterTileArray[ pointToIndex(new FlxPoint(tile_x, tile_y), widthInTiles) ] = value; | |
var c = determineTilemapFromTile(tile_x, tile_y); | |
if (activeMap[c]) | |
{ | |
//set that tilemap's tile specifically since it's onscreen / loaded already | |
if (tilemapArray[c] != null) | |
{ | |
var p = globalToLocal(tile_x, tile_y); | |
tilemapArray[c].setTile(Std.int(p.x), Std.int(p.y), value, true); | |
} | |
} | |
} | |
/** | |
* Set tile by index. | |
* @param index | |
* @param value | |
*/ | |
public function setTileByIndex(index:Int, value:Int) | |
{ | |
masterTileArray[index] = value; | |
var point = indexToPoint(index, widthInTiles); | |
var c = determineTilemapFromTile(Std.int(point.x), Std.int(point.y)); | |
if (activeMap[c]) | |
{ | |
//set that tilemap's tile specifically since it's onscreen / loaded already | |
if (tilemapArray[c] != null) | |
{ | |
var p = globalToLocal(Std.int(point.x), Std.int(point.y)); | |
tilemapArray[c].setTile(Std.int(p.x), Std.int(p.y), value, true); | |
} | |
} | |
} | |
/** | |
* Set the master tilemap from an array. | |
* @param array | |
*/ | |
public function setFromArray(array:Array<Int>) | |
{ | |
if (array.length == masterTileArray.length) | |
{ | |
masterTileArray = array; | |
for (i in 0...activeMap.length) | |
{ | |
if (activeMap[i]) | |
{ | |
deactivate(i); | |
activate(i); | |
} | |
} | |
} | |
} | |
/** | |
* Activate (and create) tilemaps by index. | |
* @param index | |
*/ | |
public function activate(index:Int) | |
{ | |
activeMap[index] = true; | |
var cur = new FlxTilemap(); | |
var pos = indexToPoint(index, width); | |
cur.setPosition((pos.x) * (sizeOfTilemap * tileSize), (pos.y) * (sizeOfTilemap * tileSize)); | |
cur.widthInTiles = sizeOfTilemap; | |
cur.heightInTiles = sizeOfTilemap; | |
var topleft = localToGlobal(0, 0, index); | |
var tiles = getTileSubset(masterTileArray, widthInTiles, Math.round(topleft.x), Math.round(topleft.y), sizeOfTilemap, sizeOfTilemap); | |
cur.loadMap(tiles, imageData, tileSize, tileSize, 0, 0, 1); | |
cur.updateFrameData(); | |
tilemapArray[index] = cur; | |
FlxG.state.add(cur); | |
} | |
/** | |
* Deactivate (and destroy) tilemaps by index. | |
* @param index | |
*/ | |
public function deactivate(index:Int) | |
{ | |
if (tilemapArray[index] != null) | |
{ | |
activeMap[index] = false; | |
tilemapArray[index].destroy(); | |
tilemapArray[index] = null; | |
} | |
} | |
/** | |
* Clear tilemaps which have been deactivated (via activeMap accesses) but not destroyed yet. | |
*/ | |
public function clearInactiveTilemaps() | |
{ | |
for (i in 0...activeMap.length) | |
{ | |
if (!activeMap[i]) | |
{ | |
if (tilemapArray[i] != null) | |
{ | |
tilemapArray[i].destroy(); | |
tilemapArray[i] = null; | |
} | |
} | |
} | |
} | |
private function getTileSubset(array:Array<Int>, total_width:Int, x:Int, y:Int, selection_width:Int, selection_height:Int):Array<Int> | |
{ | |
var a:Array<Int> = []; | |
var cur = pointToIndex(new FlxPoint(x, y), total_width); | |
for (i in 0...selection_height) | |
{ | |
for (i in cur...(cur + selection_width)) | |
{ | |
a.push(array[i]); | |
} | |
cur += total_width; | |
} | |
return a; | |
} | |
private function determineTilemapFromTile(tile_x:Int, tile_y:Int):Int | |
{ | |
var tilemap_x = Math.floor(tile_x / sizeOfTilemap); | |
var tilemap_y = Math.floor(tile_y / sizeOfTilemap); | |
return pointToIndex(new FlxPoint(tilemap_x, tilemap_y), width); | |
} | |
private function globalToLocal(global_x:Int, global_y:Int):FlxPoint | |
{ | |
var local_x = ((global_x / sizeOfTilemap) % 1) * sizeOfTilemap; | |
var local_y = ((global_y / sizeOfTilemap) % 1) * sizeOfTilemap; | |
return new FlxPoint(local_x, local_y); | |
} | |
private function localToGlobal(local_x:Int, local_y:Int, tilemapIndex:Int):FlxPoint | |
{ | |
var ind:Int = 0; | |
var pos = indexToPoint(tilemapIndex, width); | |
ind += Std.int(pos.y * sizeOfTilemap * widthInTiles); | |
ind += Std.int(pos.x * sizeOfTilemap); | |
ind += pointToIndex(new FlxPoint(local_x, local_y), widthInTiles); | |
return indexToPoint(ind, widthInTiles); | |
} | |
private function indexToPoint(index:Int, width:Int):FlxPoint | |
{ | |
var p = new FlxPoint(0, 0); | |
p.y = Math.floor(index / width); | |
p.x = Math.round(((index / width) % 1) * width); | |
return p; | |
} | |
private function pointToIndex(p:FlxPoint, width:Int):Int | |
{ | |
var i = 0; | |
i = Std.int(p.y * width + p.x); | |
return i; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment