excaliburjs / excalibur-aseprite

Aseprite plugin for Excalibur
BSD 2-Clause "Simplified" License
3 stars 9 forks source link

Toggling layer visibility at runtime #242

Open mattjennings opened 7 months ago

mattjennings commented 7 months ago

Context

It would be very handy if it were possible to toggle visibility of certain layers on/off during a game. This should be possible for both native & json file formats as it seems the json export allows you to split the layers.

Proposal

I did a bit of digging through the source, and I think at a high level this might look like:

Not sure how well this concept of animation frames being a GraphicsGroup fits into the ex.Animation class. Maybe the logic for layering should be done there, and then this plugin would just parse them appropriately.

Caveats

With a json export, the image is exported with split layers is all in 1 image so there is potential for it to get very big with many layers. But with a native resource it seems like the parser writes to a canvas to make the image source, so maybe we could parse each layer as its own image source to keep the texture size low?

mattjennings commented 7 months ago

A simpler solution might be to allow parsing on a given layer name, and then let the user cobble them together however they see fit


Just did a quick PoC and this is pretty trivial to do with the native parser. However, the json export is a bit trickier. Example of a "split layer" json export (it seems to be the only link of frame to layer is (Layer Name) in the frame name)

{ "frames": {
   "beetle (Layer 1) 0.aseprite": {
    "frame": { "x": 0, "y": 0, "w": 64, "h": 64 },
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
    "sourceSize": { "w": 64, "h": 64 },
    "duration": 500
   },
   "beetle (Layer 1) 1.aseprite": {
    "frame": { "x": 64, "y": 0, "w": 64, "h": 64 },
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
    "sourceSize": { "w": 64, "h": 64 },
    "duration": 500
   },
   "beetle (Layer 1) 2.aseprite": {
    "frame": { "x": 128, "y": 0, "w": 64, "h": 64 },
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
    "sourceSize": { "w": 64, "h": 64 },
    "duration": 500
   },
   "beetle (Layer 2) 0.aseprite": {
    "frame": { "x": 0, "y": 64, "w": 64, "h": 64 },
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
    "sourceSize": { "w": 64, "h": 64 },
    "duration": 500
   },
   "beetle (Layer 2) 1.aseprite": {
    "frame": { "x": 64, "y": 64, "w": 64, "h": 64 },
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
    "sourceSize": { "w": 64, "h": 64 },
    "duration": 500
   },
   "beetle (Layer 2) 2.aseprite": {
    "frame": { "x": 128, "y": 64, "w": 64, "h": 64 },
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
    "sourceSize": { "w": 64, "h": 64 },
    "duration": 500
   }
 },
 "meta": {
  "app": "https://www.aseprite.org/",
  "version": "1.3-rc6-arm64",
  "image": "beetle-layers.png",
  "format": "RGBA8888",
  "size": { "w": 192, "h": 128 },
  "scale": "1",
  "frameTags": [
   { "name": "Loop", "from": 0, "to": 2, "direction": "pingpong", "color": "#000000ff" },
   { "name": "Animation 2", "from": 1, "to": 2, "direction": "reverse", "color": "#000000ff" }
  ],
  "layers": [
   { "name": "Layer 1", "opacity": 255, "blendMode": "normal" },
   { "name": "Layer 2", "opacity": 255, "blendMode": "normal" }
  ],
  "slices": [
  ]
 }
}