The Blog

May 23rd, 2011Game DevelopmentJames 16 Comments

I find the optimal layout of a sprite-sheet is one that starts from the left [0,0] and ends to the right [n-1,0]. This way there is as little space wasted compared to a more common multi dimensional version.

For every artist that uses “Adobe Photoshop” (CS4 and CS5) creating these images requires created many layers of images, and finally a labour-intensive merge; merging them into one file specified by:

Image size = (width per frame * quantity)*(height per frame*quantity)

There are other ways such as making the full image size and filling in each frame, either way it can be annoying to merge/assemble the frames within each frames dimension…

The script (that can be downloaded here) can be run internally via Photoshop Cs4 and Cs5 to automate the build process. To show it off I have set up a mini tutorial to cover it using Cs5.

Step 1:

Open photo-shop and click on File/Scripts/Load Files Onto Stack…

Note: For non CS5 users try the “Automate/Photomerge” tool to stack your images up!

Step 2:

Click “browse” and select each individual image that represents the frames you want to merge.

Then press OK.

Step 3:

Photoshop will do some funky stuff, you may see your screen flash as it is pushing/popping each frame onto your layers. In the end you will get something like this:

Step 4:

Go to File/Scripts/Browse

Select the script and let it do its work!

It will process each layer and batch them efficiently into one image.

Limitations

There are some limitations:

  • The width and height of each frame must be the same
  • The files must be image formats
  • Sheets are ordered from the bottom layer to the top
  • This works well for Photoshop Cs4 and Cs5 however lower versions may not, instead use the “Photo merge” (Files/Automation/Photo merge) using a reposition setting (if available) with no merging to add images to the layers

16 comments on “Generate a sprite sheet using layers in Photoshop

  1. anonymous on said:

    I’m using photoshop cs5 12.1 Extended and I got an error when I tried to run the script:
    Error 8800: General Photoshop Error occured. This functionality may not be available in this version of Photoshop.
    -The command “Show” is not currently available.
    Line: 23
    -> docRef.artLayers[i].visible = true;

    Any suggestions?

    • Hello, I have not tested the file on that version of photoshop I am afraid, I will look into it soon for you!
      I appears that in the latest version Adobe have changed some of the API that I used to get the current visibility of a layer,
      sorry for the inconvenience !

      On a side note, you are my first “real” comment so I thank you :D

  2. Prasad on said:

    Thanks for the script. It come to use for me. I am using CS4 and “msg” function is not available in CS4. Ofcourse the function “alert” worked.

    Thanks
    Prasad

    • I see, I am not sure if you have solved it but just in case you haven’t:
      Remove :

      else
      {
      msg(“Sorry must have more than 1 image open in photoshop to work!”);
      }

      And the error should go away :)

  3. Just tried to use your script and I got a similar error.

    - Could not transform because the initial bounding rectangle is empty.
    Line: 27
    -> docRef.artLayers[i].translate(movX, 0);

    • I am not entirely sure but, ensure that the layer has something on.
      I believe it needs to:

      1 – have something on it
      2 – Not be a background layer (just make it a standard layer instead)

      - Hope it helps :D

  4. This works like a magic! Im using PS 5.1.
    This really saved me so much time!! Cant thank you enough for this!!
    Cheers
    Vamsi

  5. Mikael on said:

    Hey man :) Thanks for the script. A friend/coworker of mine Martin Hagstedt created a modified version of this script that lets you define the number of rows the sprite sheet will have. I have used it here in ver 5.1 on a game production in Sweden a lot. Cheers!

    /Mikael

    if (documents.length > 0)
    {
    var docRef = activeDocument;
    var activeLayer = docRef.activeLayer;
    var numLayers = docRef.artLayers.length;

    // Ask for number of rows
    var spritesPerRow = parseInt( prompt(“How many sprites per rows?”, numLayers) );

    var spriteX = docRef.width;
    var spriteY = docRef.height;

    var numRows = Math.ceil(numLayers / spritesPerRow);

    app.preferences.rulerUnits = Units.PIXELS;
    docRef.resizeCanvas( spriteX * spritesPerRow, spriteY * numRows, AnchorPosition.TOPLEFT );

    var currentLayer = 0;

    for( i = 0; i < numRows; i++ ) {
    for( j=0; j = numLayers )
    break;

    var destX = spriteX * j;
    var destY = spriteY * i;

    // Only translate non-empty layers
    if (!(docRef.artLayers[currentLayer].kind == LayerKind.NORMAL
    && docRef.artLayers[currentLayer].bounds[2] == 0
    && docRef.artLayers[currentLayer].bounds[3] == 0)) {

    docRef.artLayers[currentLayer].visible = true;
    docRef.artLayers[currentLayer].translate(destX, destY);
    }

    currentLayer++;
    }
    }

    } else {

    alert(“Nothing to work with!”);

    }

    • Very nice :)
      Always happy to help, your one is more user friendly that is for sure!

      Let me know how the game turns out.

      - James

    • Raffy on said:

      Newbie here. PS CS4. I’m getting a:

      Error 8: Syntax error.

      Line:9
      - > var currentLayer += 0;

      I’m I missing something?

      Thank you.

  6. Pingback: Photoshop Sprite Map Script | Icepick66

  7. Pingback: Photoshop Sprite Map Script | Icepick66

  8. boneless on said:

    // Save this file in Program Files\Adobe\Photoshop\Presets\Scripts\
    // In PhotoShop CS5, run it by going menu File > SCripts > Browse > layersToSprite.js

    if (documents.length > 0) {

    // Adjust this to the number of columns you want
    //leave -1 if you want it to calculate an optimal column value.
    var cols = -1;

    var docRef = activeDocument;
    var numLayers = docRef.artLayers.length;

    if (cols < 0) {
    var sqrt = Math.floor( Math.sqrt(numLayers));
    if (Math.sqrt(numLayers) % sqrt == 0) {
    cols = sqrt;
    }else {
    for (i = sqrt+1; i <= numLayers ; i++){
    if (numLayers % i == 0) {
    cols = i;
    break;
    }
    }
    }

    if (cols = 0; i–)
    {
    docRef.artLayers[i].visible = 1;

    var movX = spriteX*coli;
    var movY = spriteY*rowi;

    docRef.artLayers[i].translate(movX, movY);

    coli++;
    if (coli > (cols – 1))
    {
    rowi++;
    coli = 0;
    }
    }
    }

  9. Ignivome on said:

    Wow man, thanks a lot! Your a lifesaver

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>