Using brl.json to parse Texture Packer json files
Monkey Forums/Monkey Programming/Using brl.json to parse Texture Packer json files| 
 | ||
| Texture Packer outputs the following json: 
{"frames": {
    
"frame-abc.png":
{
	"frame": {"x":41,"y":2,"w":256,"h":256},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":256,"h":256},
	"sourceSize": {"w":256,"h":256}
},
"someframe":
{
	"frame": {"x":2,"y":2,"w":37,"h":382},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":37,"h":382},
	"sourceSize": {"w":37,"h":382}
}
}
}
Yet I am having a hard time parsing it using brl.json... in fact I don't know where to start!! :( This is what I've got so far and its not much: 		Local str:String = LoadString("sprites.json")
		Local jso:JsonObject = New JsonObject(str)
		Local sprites:JsonValue = jso.Get("frames")
		Print sprites.ToJson()
This outputs all the frames to the console, but how do I parse those objects to create "sprites"? | 
| 
 | ||
| Must have been tired last night: Still not happy about changing the "objects" to json all the time... and its fugly... but it works... | 
| 
 | ||
| You could use GetData() to retrieve the underlying StringMap<JsonValue>, then iterate through the map, eg: 
Local str:=LoadString("sprites.json")
Local jso:=New JsonObject(str)
Local sprs:=JsonObject( jso.Get("frames") )
For Local it:=EachIn sprs.GetData()
   Local key:=it.Key                 'eg: frame-abc.png
   Local spr:=JsonObject( it.Value )
   Local frame:=JsonObject( spr.Get( "frame" ) )
   Print "x,y,w,h="+frame.GetInt( "x" )...etc...
Next
(IMO, frames should really be an array...) There's an issue if the order of the frames is important, in which case brl.json would need to be modified, eg: a GetOrderedKeys:String[]() method could be added to JsonObject... | 
| 
 | ||
| Ah thats a lot nicer! Thanks Mark! And I do agree that Frames should be an array, but its not my format ;) Oh, just found out the TexturePacker can output two types of JSON, one in Hash format (above) and Array based (below): {"frames": [
{
	"filename": "axe.png",
	"frame": {"x":2,"y":364,"w":128,"h":126},
	"rotated": true,
	"trimmed": true,
	"spriteSourceSize": {"x":0,"y":1,"w":128,"h":126},
	"sourceSize": {"w":128,"h":128}
},
{
	"filename": "sword.png",
	"frame": {"x":117,"y":199,"w":126,"h":126},
	"rotated": false,
	"trimmed": true,
	"spriteSourceSize": {"x":1,"y":0,"w":126,"h":126},
	"sourceSize": {"w":128,"h":128}
}],
"meta": {
	"app": "http://www.codeandweb.com/texturepacker ",
	"version": "1.0",
	"image": "array.png",
	"format": "RGBA8888",
	"size": {"w":256,"h":542},
	"scale": "1",
	"smartupdate": "$TexturePacker:SmartUpdate:<SNIP>"
}
} | 
| 
 | ||
| You don't have to use JSON as an exporter from texturepacker, I prefer simple textfiles. Put the following in a textfile and save under TexturePacker\bin\exporters\[yourname] to get a simple one line per image file. {% for sprite in allSprites %}{{sprite.trimmedName}} {{sprite.frameRect.x}} {{sprite.frameRect.y}} {{sprite.frameRect.width}} {{sprite.frameRect.height}} {{sprite.cornerOffset.x}} {{sprite.cornerOffset.y}} {{sprite.untrimmedSize.width}} {{sprite.untrimmedSize.height}} {% if sprite.rotated %}1{% else %}0{% endif %}{% if not forloop.last %}
{% endif %}{% endfor %}Then copy exporter.xml from another exporter in \exporters\ to your dir and change the name etc in the xml file. It should have the following values: <fileExtension>txt</fileExtension> <supportsTrimming>yes</supportsTrimming> <supportsRotation>yes</supportsRotation> <rotationDirection>cw</rotationDirection> <supportsNPOT>no</supportsNPOT> <supportsTrimSpriteNames>yes</supportsTrimSpriteNames> <supportsTextureSubPath>yes</supportsTextureSubPath> Here's an image class that can load from the above exporter: Class bbImage
  Field Name:String
  Field Width
  Field Height
  Field OffX
  Field OffY
  Field Rotated? 'If rotated in textureatlas to save space
  Field Img:Image
  Method Draw(atx#,aty#)
    If Rotated Then
      DrawImage(Img, atx+OffX, aty + OffY + Width, 90,1,1)
    Else
      DrawImage(Img, atx+OffX, aty+OffY)
    End
  End
  Function LoadFromTexturePacker:bbImage[](filename:String)
    Local Atlas := LoadImage(filename+".png")
    If Atlas = Null Then
      Error "Can't find ~q"+filename+"~q"
      Return
    End
    Local lines := app.LoadString(filename+".txt").Split("~n")[1..]
    Local result := New List<bbImage>()
    For Local i := Eachin lines
       Local c := i.Split(" ")
       Local bb := New bbImage()
       bb.Name = c[0]
       Local x := Int(c[1])
       Local y := Int(c[2])
       Local w := Int(c[3])
       Local h := Int(c[4])
       bb.Img = Atlas.GrabImage(x,y,w,h)
       bb.OffX   = Int(c[5])
       bb.OffY   = Int(c[6])
       bb.Width = Int(c[7])
       bb.Height = Int(c[8])
       bb.Rotated = Int(c[9]) = 1
       result.AddLast(bb)
    End
    Return result.ToArray()
  End
End
 | 
| 
 | ||
| Thanks Erik, I was also using it to learn how to use the brl.json module :) One thing with the JSON output from TexturePacker is that it doesn't tell you what rotation to do if the image has been rotated, which is weird... |