2013-11-27 16:33:49 +00:00
/ * *
* @ author Richard Davey < rich @ photonstorm . com >
2014-02-05 05:54:25 +00:00
* @ copyright 2014 Photon Storm Ltd .
2013-11-27 16:33:49 +00:00
* @ license { @ link https : //github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
* /
/ * *
* Phaser . TilemapParser parses data objects from Phaser . Loader that need more preparation before they can be inserted into a Tilemap .
*
* @ class Phaser . TilemapParser
* /
2013-10-11 03:42:11 +00:00
Phaser . TilemapParser = {
2013-11-27 16:33:49 +00:00
/ * *
* Creates a Tileset object .
* @ method Phaser . TilemapParser . tileset
* @ param { Phaser . Game } game - Game reference to the currently running game .
2013-12-13 14:04:14 +00:00
* @ param { string } key - The Cache key of this tileset .
2013-12-18 00:44:04 +00:00
* @ param { number } tileWidth - Width of each single tile in pixels .
* @ param { number } tileHeight - Height of each single tile in pixels .
2013-12-13 14:04:14 +00:00
* @ param { number } [ tileMargin = 0 ] - If the tiles have been drawn with a margin , specify the amount here .
* @ param { number } [ tileSpacing = 0 ] - If the tiles have been drawn with spacing between them , specify the amount here .
2013-12-18 00:44:04 +00:00
* @ param { number } [ rows = - 1 ] - How many tiles are placed horizontally in each row ? If - 1 it will calculate rows by dividing the image width by tileWidth .
* @ param { number } [ columns = - 1 ] - How many tiles are placed vertically in each column ? If - 1 it will calculate columns by dividing the image height by tileHeight .
* @ param { number } [ total = - 1 ] - The maximum number of tiles to extract from the image . If - 1 it will extract ` rows * columns ` worth . You can also set a value lower than the actual number of tiles .
2013-11-27 16:33:49 +00:00
* @ return { Phaser . Tileset } Generated Tileset object .
* /
2013-12-18 00:44:04 +00:00
tileset : function ( game , key , tileWidth , tileHeight , tileMargin , tileSpacing , rows , columns , total ) {
2013-11-25 04:40:04 +00:00
// How big is our image?
var img = game . cache . getTilesetImage ( key ) ;
2013-12-18 00:44:04 +00:00
if ( img === null )
2013-11-25 04:40:04 +00:00
{
2013-12-18 00:44:04 +00:00
console . warn ( "Phaser.TilemapParser.tileSet: Invalid image key given" ) ;
2013-11-25 04:40:04 +00:00
return null ;
}
var width = img . width ;
var height = img . height ;
2013-12-18 00:44:04 +00:00
if ( rows === - 1 )
2013-11-25 04:40:04 +00:00
{
2013-12-18 00:44:04 +00:00
rows = Math . round ( width / tileWidth ) ;
2013-11-25 04:40:04 +00:00
}
2013-12-18 00:44:04 +00:00
if ( columns === - 1 )
2013-11-25 04:40:04 +00:00
{
2013-12-18 00:44:04 +00:00
columns = Math . round ( height / tileHeight ) ;
2013-11-25 04:40:04 +00:00
}
2013-12-18 00:44:04 +00:00
if ( total === - 1 )
2013-11-25 04:40:04 +00:00
{
2013-12-18 00:44:04 +00:00
total = rows * columns ;
2013-11-25 04:40:04 +00:00
}
2013-12-18 00:44:04 +00:00
2013-11-25 04:40:04 +00:00
// Zero or smaller than tile sizes?
if ( width === 0 || height === 0 || width < tileWidth || height < tileHeight || total === 0 )
{
console . warn ( "Phaser.TilemapParser.tileSet: width/height zero or width/height < given tileWidth/tileHeight" ) ;
return null ;
}
2013-12-18 00:44:04 +00:00
return new Phaser . Tileset ( img , key , tileWidth , tileHeight , tileMargin , tileSpacing , rows , columns , total ) ;
2013-10-11 05:30:28 +00:00
2013-11-25 04:40:04 +00:00
} ,
2013-10-11 05:30:28 +00:00
2013-11-27 16:33:49 +00:00
/ * *
2014-02-21 10:06:53 +00:00
* Parse tilemap data from the cache and creates a Tilemap object .
2013-11-27 16:33:49 +00:00
* @ method Phaser . TilemapParser . parse
* @ param { Phaser . Game } game - Game reference to the currently running game .
2013-12-18 16:56:14 +00:00
* @ param { string } key - The key of the tilemap in the Cache .
* @ return { object } The parsed map object .
2013-11-27 16:33:49 +00:00
* /
2013-12-18 16:56:14 +00:00
parse : function ( game , key ) {
var map = game . cache . getTilemapData ( key ) ;
2013-10-11 05:30:28 +00:00
2013-12-18 16:56:14 +00:00
if ( map )
2013-11-25 04:40:04 +00:00
{
2013-12-18 16:56:14 +00:00
if ( map . format === Phaser . Tilemap . CSV )
{
return this . parseCSV ( map . data ) ;
}
else if ( map . format === Phaser . Tilemap . TILED _JSON )
{
return this . parseTiledJSON ( map . data ) ;
}
2013-11-25 04:40:04 +00:00
}
2013-12-18 16:56:14 +00:00
else
2013-11-25 04:40:04 +00:00
{
2014-02-18 03:01:51 +00:00
return this . getEmptyData ( ) ;
2013-11-25 04:40:04 +00:00
}
2013-10-11 05:30:28 +00:00
2013-11-25 04:40:04 +00:00
} ,
2013-10-11 05:30:28 +00:00
2013-11-25 04:40:04 +00:00
/ * *
2013-11-27 16:33:49 +00:00
* Parses a CSV file into valid map data .
* @ method Phaser . TilemapParser . parseCSV
* @ param { string } data - The CSV file data .
* @ return { object } Generated map data .
2013-11-25 04:40:04 +00:00
* /
parseCSV : function ( data ) {
2013-10-11 03:42:11 +00:00
2013-11-25 04:40:04 +00:00
// Trim any rogue whitespace from the data
data = data . trim ( ) ;
2013-10-11 03:42:11 +00:00
2013-11-25 04:40:04 +00:00
var output = [ ] ;
var rows = data . split ( "\n" ) ;
var height = rows . length ;
var width = 0 ;
2013-10-11 17:18:27 +00:00
2013-11-25 04:40:04 +00:00
for ( var i = 0 ; i < rows . length ; i ++ )
{
output [ i ] = [ ] ;
2013-10-11 03:42:11 +00:00
2013-11-25 04:40:04 +00:00
var column = rows [ i ] . split ( "," ) ;
2013-10-11 05:30:28 +00:00
2013-11-25 04:40:04 +00:00
for ( var c = 0 ; c < column . length ; c ++ )
{
output [ i ] [ c ] = parseInt ( column [ c ] , 10 ) ;
}
2013-10-11 05:30:28 +00:00
2013-11-25 04:40:04 +00:00
if ( width === 0 )
{
width = column . length ;
}
}
2013-12-05 18:12:16 +00:00
// Build collision map
2013-11-25 04:40:04 +00:00
return [ { name : 'csv' , width : width , height : height , alpha : 1 , visible : true , indexes : [ ] , tileMargin : 0 , tileSpacing : 0 , data : output } ] ;
} ,
2013-10-11 05:30:28 +00:00
2014-02-18 03:01:51 +00:00
/ * *
* Returns an empty map data object .
* @ method Phaser . TilemapParser . getEmptyData
* @ return { object } Generated map data .
* /
getEmptyData : function ( ) {
var map = { } ;
map . width = 0 ;
map . height = 0 ;
map . tileWidth = 0 ;
map . tileHeight = 0 ;
map . orientation = 'orthogonal' ;
map . version = '1' ;
map . properties = { } ;
map . widthInPixels = 0 ;
map . heightInPixels = 0 ;
var layers = [ ] ;
var layer = {
name : 'layer' ,
x : 0 ,
y : 0 ,
width : 0 ,
height : 0 ,
widthInPixels : 0 ,
heightInPixels : 0 ,
alpha : 1 ,
visible : true ,
properties : { } ,
indexes : [ ] ,
callbacks : [ ] ,
data : [ ]
} ;
layers . push ( layer ) ;
map . layers = layers ;
map . images = [ ] ;
map . objects = { } ;
map . collision = { } ;
map . tilesets = [ ] ;
map . tiles = [ ] ;
return map ;
} ,
2013-11-25 04:40:04 +00:00
/ * *
2013-11-27 16:33:49 +00:00
* Parses a Tiled JSON file into valid map data .
* @ method Phaser . TilemapParser . parseJSON
2013-12-18 16:56:14 +00:00
* @ param { object } json - The JSON map data .
* @ return { object } Generated and parsed map data .
2013-11-25 04:40:04 +00:00
* /
parseTiledJSON : function ( json ) {
2013-10-11 05:30:28 +00:00
2013-12-19 03:49:28 +00:00
if ( json . orientation !== 'orthogonal' )
{
console . warn ( 'TilemapParser.parseTiledJSON: Only orthogonal map types are supported in this version of Phaser' ) ;
return null ;
}
// Map data will consist of: layers, objects, images, tilesets, sizes
2013-12-18 04:40:10 +00:00
var map = { } ;
2013-12-05 18:12:16 +00:00
2013-12-19 03:49:28 +00:00
map . width = json . width ;
map . height = json . height ;
map . tileWidth = json . tilewidth ;
map . tileHeight = json . tileheight ;
map . orientation = json . orientation ;
map . version = json . version ;
map . properties = json . properties ;
map . widthInPixels = map . width * map . tileWidth ;
map . heightInPixels = map . height * map . tileHeight ;
2013-12-18 04:40:10 +00:00
// Tile Layers
2013-11-25 04:40:04 +00:00
var layers = [ ] ;
for ( var i = 0 ; i < json . layers . length ; i ++ )
{
2013-12-18 04:40:10 +00:00
if ( json . layers [ i ] . type !== 'tilelayer' )
2013-11-25 04:40:04 +00:00
{
continue ;
}
var layer = {
name : json . layers [ i ] . name ,
2013-12-05 18:12:16 +00:00
x : json . layers [ i ] . x ,
y : json . layers [ i ] . y ,
2013-11-25 04:40:04 +00:00
width : json . layers [ i ] . width ,
height : json . layers [ i ] . height ,
2013-12-19 03:49:28 +00:00
widthInPixels : json . layers [ i ] . width * json . tilewidth ,
heightInPixels : json . layers [ i ] . height * json . tileheight ,
2013-11-25 04:40:04 +00:00
alpha : json . layers [ i ] . opacity ,
visible : json . layers [ i ] . visible ,
2013-12-05 18:12:16 +00:00
properties : { } ,
2014-01-14 22:34:41 +00:00
indexes : [ ] ,
2014-02-18 03:01:51 +00:00
callbacks : [ ] ,
bodies : [ ]
2013-11-25 04:40:04 +00:00
} ;
2013-12-05 18:12:16 +00:00
if ( json . layers [ i ] . properties )
{
layer . properties = json . layers [ i ] . properties ;
}
var x = 0 ;
var row = [ ] ;
2013-11-25 04:40:04 +00:00
var output = [ ] ;
2013-12-05 18:12:16 +00:00
// Loop through the data field in the JSON.
// This is an array containing the tile indexes, one after the other. 0 = no tile, everything else = the tile index (starting at 1)
2014-01-14 22:34:41 +00:00
// If the map contains multiple tilesets then the indexes are relative to that which the set starts from.
2013-12-05 18:12:16 +00:00
// Need to set which tileset in the cache = which tileset in the JSON, if you do this manually it means you can use the same map data but a new tileset.
2013-11-25 04:40:04 +00:00
2013-12-18 04:40:10 +00:00
for ( var t = 0 , len = json . layers [ i ] . data . length ; t < len ; t ++ )
2013-11-25 04:40:04 +00:00
{
2013-12-05 18:12:16 +00:00
// index, x, y, width, height
if ( json . layers [ i ] . data [ t ] > 0 )
{
2014-01-14 22:34:41 +00:00
row . push ( new Phaser . Tile ( layer , json . layers [ i ] . data [ t ] , x , output . length , json . tilewidth , json . tileheight ) ) ;
2013-12-05 18:12:16 +00:00
}
else
{
row . push ( null ) ;
}
x ++ ;
if ( x === json . layers [ i ] . width )
{
output . push ( row ) ;
x = 0 ;
row = [ ] ;
}
2013-12-18 04:40:10 +00:00
}
2013-12-05 18:12:16 +00:00
2013-12-18 04:40:10 +00:00
layer . data = output ;
2013-12-05 18:12:16 +00:00
2013-12-18 04:40:10 +00:00
layers . push ( layer ) ;
}
map . layers = layers ;
// Images
var images = [ ] ;
2013-11-25 04:40:04 +00:00
2013-12-18 04:40:10 +00:00
for ( var i = 0 ; i < json . layers . length ; i ++ )
{
if ( json . layers [ i ] . type !== 'imagelayer' )
{
continue ;
}
2013-12-05 18:12:16 +00:00
2013-12-18 04:40:10 +00:00
var image = {
name : json . layers [ i ] . name ,
image : json . layers [ i ] . image ,
x : json . layers [ i ] . x ,
y : json . layers [ i ] . y ,
alpha : json . layers [ i ] . opacity ,
visible : json . layers [ i ] . visible ,
properties : { }
} ;
if ( json . layers [ i ] . properties )
{
image . properties = json . layers [ i ] . properties ;
}
2013-11-25 04:40:04 +00:00
2013-12-18 04:40:10 +00:00
images . push ( image ) ;
}
map . images = images ;
2014-02-18 03:01:51 +00:00
// Objects & Collision Data (polylines, etc)
2013-12-23 04:19:52 +00:00
var objects = { } ;
2014-02-18 03:01:51 +00:00
var collision = { } ;
2013-12-18 04:40:10 +00:00
for ( var i = 0 ; i < json . layers . length ; i ++ )
{
if ( json . layers [ i ] . type !== 'objectgroup' )
{
continue ;
}
2013-12-23 04:19:52 +00:00
objects [ json . layers [ i ] . name ] = [ ] ;
2014-02-18 03:01:51 +00:00
collision [ json . layers [ i ] . name ] = [ ] ;
2013-12-23 04:19:52 +00:00
for ( var v = 0 , len = json . layers [ i ] . objects . length ; v < len ; v ++ )
2013-12-18 04:40:10 +00:00
{
2014-02-18 03:01:51 +00:00
// Object Tiles
2013-12-18 04:40:10 +00:00
if ( json . layers [ i ] . objects [ v ] . gid )
2013-11-25 04:40:04 +00:00
{
2013-12-18 04:40:10 +00:00
var object = {
gid : json . layers [ i ] . objects [ v ] . gid ,
name : json . layers [ i ] . objects [ v ] . name ,
x : json . layers [ i ] . objects [ v ] . x ,
y : json . layers [ i ] . objects [ v ] . y ,
visible : json . layers [ i ] . objects [ v ] . visible ,
properties : json . layers [ i ] . objects [ v ] . properties
} ;
2013-12-23 04:19:52 +00:00
objects [ json . layers [ i ] . name ] . push ( object ) ;
2013-11-25 04:40:04 +00:00
}
2014-02-18 03:01:51 +00:00
else if ( json . layers [ i ] . objects [ v ] . polyline )
{
var object = {
name : json . layers [ i ] . objects [ v ] . name ,
x : json . layers [ i ] . objects [ v ] . x ,
y : json . layers [ i ] . objects [ v ] . y ,
width : json . layers [ i ] . objects [ v ] . width ,
height : json . layers [ i ] . objects [ v ] . height ,
visible : json . layers [ i ] . objects [ v ] . visible ,
properties : json . layers [ i ] . objects [ v ] . properties
} ;
object . polyline = [ ] ;
// Parse the polyline into an array
for ( var p = 0 ; p < json . layers [ i ] . objects [ v ] . polyline . length ; p ++ )
{
object . polyline . push ( [ json . layers [ i ] . objects [ v ] . polyline [ p ] . x , json . layers [ i ] . objects [ v ] . polyline [ p ] . y ] ) ;
}
collision [ json . layers [ i ] . name ] . push ( object ) ;
}
2013-12-18 04:40:10 +00:00
2013-11-25 04:40:04 +00:00
}
2013-12-18 04:40:10 +00:00
}
2013-10-11 05:30:28 +00:00
2013-12-18 04:40:10 +00:00
map . objects = objects ;
2014-02-18 03:01:51 +00:00
map . collision = collision ;
2013-12-05 18:12:16 +00:00
2013-12-18 04:40:10 +00:00
// Tilesets
var tilesets = [ ] ;
2013-12-19 03:49:28 +00:00
for ( var i = 0 ; i < json . tilesets . length ; i ++ )
2013-12-18 16:56:14 +00:00
{
2013-12-19 03:49:28 +00:00
// name, firstgid, width, height, margin, spacing, properties
var set = json . tilesets [ i ] ;
var newSet = new Phaser . Tileset ( set . name , set . firstgid , set . tilewidth , set . tileheight , set . margin , set . spacing , set . properties ) ;
2013-12-18 16:56:14 +00:00
2013-12-19 03:49:28 +00:00
if ( set . tileproperties )
2013-12-18 16:56:14 +00:00
{
2013-12-19 03:49:28 +00:00
newSet . tileProperties = set . tileproperties ;
2013-12-18 16:56:14 +00:00
}
2014-02-26 01:20:24 +00:00
newSet . rows = Math . round ( ( set . imageheight - set . margin ) / ( set . tileheight + set . spacing ) ) ;
newSet . columns = Math . round ( ( set . imagewidth - set . margin ) / ( set . tilewidth + set . spacing ) ) ;
2013-12-19 03:49:28 +00:00
newSet . total = newSet . rows * newSet . columns ;
2013-12-18 16:56:14 +00:00
2014-02-21 16:57:45 +00:00
if ( newSet . rows % 1 !== 0 || newSet . columns % 1 !== 0 )
{
console . warn ( 'TileSet image dimensions do not match expected dimensions. Tileset width/height must be evenly divisible by Tilemap tile width/height.' ) ;
}
else
{
tilesets . push ( newSet ) ;
}
2013-12-19 03:49:28 +00:00
}
2013-12-18 16:56:14 +00:00
2013-12-19 03:49:28 +00:00
map . tilesets = tilesets ;
2013-12-18 16:56:14 +00:00
2013-12-19 03:49:28 +00:00
map . tiles = [ ] ;
2013-12-18 16:56:14 +00:00
2013-12-19 03:49:28 +00:00
// Finally lets build our super tileset index
for ( var i = 0 ; i < map . tilesets . length ; i ++ )
2013-12-18 04:40:10 +00:00
{
2013-12-19 03:49:28 +00:00
var set = map . tilesets [ i ] ;
var x = set . tileMargin ;
var y = set . tileMargin ;
2013-12-18 04:40:10 +00:00
2013-12-19 03:49:28 +00:00
var count = 0 ;
var countX = 0 ;
var countY = 0 ;
2013-12-18 04:40:10 +00:00
2013-12-19 03:49:28 +00:00
for ( var t = set . firstgid ; t < set . firstgid + set . total ; t ++ )
{
// Can add extra properties here as needed
map . tiles [ t ] = [ x , y , i ] ;
2013-12-18 16:56:14 +00:00
2013-12-19 03:49:28 +00:00
x += set . tileWidth + set . tileSpacing ;
2013-12-18 16:56:14 +00:00
2013-12-19 03:49:28 +00:00
count ++ ;
2013-10-11 05:30:28 +00:00
2013-12-19 03:49:28 +00:00
if ( count === set . total )
{
break ;
}
2013-12-18 16:56:14 +00:00
2013-12-19 03:49:28 +00:00
countX ++ ;
2013-12-18 16:56:14 +00:00
2013-12-19 03:49:28 +00:00
if ( countX === set . columns )
{
x = set . tileMargin ;
y += set . tileHeight + set . tileSpacing ;
2013-12-18 16:56:14 +00:00
2013-12-19 03:49:28 +00:00
countX = 0 ;
countY ++ ;
2013-12-18 16:56:14 +00:00
2013-12-19 03:49:28 +00:00
if ( countY === set . rows )
{
break ;
}
}
}
2013-12-18 16:56:14 +00:00
2013-11-25 04:40:04 +00:00
}
2013-10-11 03:42:11 +00:00
2013-12-18 04:40:10 +00:00
return map ;
2013-10-11 03:42:11 +00:00
2013-11-25 04:40:04 +00:00
}
2013-10-11 03:42:11 +00:00
}