Tuesday, May 28, 2013

Avoiding Name Collision for your Sprites

In Cocos2D when sprite sheets are imported the sprites within them come in as - for example - "alarm-clock.png" where this was the original name of the image, before it was composited into the sheet.

I believe Unity and other programs that use TexturePacker work a similar way.

So where is the problem?

Well, what if you have two different alarm clocks?  Or two different images for the same clock?

Collision avoidance!
Even if you have different sprite sheets, all images go into the same name space and because you are not using any kind of directory structure - that was all lost when it was imported into Texture Packer - then you have an issue with name collision.

You have to start prefixing the alarm clock with "blue-alarm-clock.png" or "alarm-clock-1.png" but then it becomes a tussle to figure out what the original clock was, maybe still just named without any prefix.

It becomes very easy for one sprite in your game to wind up being substituted in for another without you realising it and unless you test every branch of the game, you might not notice until its too late and the game has shipped already!

Here's a quick way to disambiguate your images for your sprites, that uses the command line on the mac: embed the sha1sum signature of the image into the filename.  That way as long as the image is different it will have a different file name from any other image sprite file in your game guaranteed.

The key to it is the shasum command which is installed in Mac by default.  If your version of MacOS doesnt' have "shasum" you will probably find that an equivalent tool is installed that you can use - try md5sum or similar.  Same if you're on Windows using Cygwin or minGW-sys.

Here's the code we're going to use, laid out on different lines:

for f in sprites/*.png; do 
    g=$(shasum $f)
    h=${g:0:7};
    b=$(basename $f .png) 
    d=$(dirname $f)
    echo mv -v $f $d/$b-$h.png
done

What this is doing is getting the variable "f" to take on the string value of every file name in your sprites directory that ends with ".png", each time through the "for" loop.  Inside the loop, we store into variable "g" the sha1sum of the file which is a long string that looks like this:

~/Documents/Artwork/seperations-game-ready/main-room sez$ shasum sprites/alarm-clock.png 
1dcd66fcb214b1875ebd28cff83dedf83960707  sprites/alarm-clock.png

Since we only need a few characters from the long sha1 string, the next line is getting a substring of our g variable taking the first 7 characters only.  That also conveniently ignores the trailing filename which is repeated.

Finally we use the basename and dirname built-in bash functions to get the parts of the file name that we need, so we can stitch it back together in the move command.

Note that as per my usual practice I use "echo" so that instead of the move actually executing it just prints out what it would do.

Now we can run this command by opening a Terminal session, changing directory to the directory containing our sprites directory, then run it all on one line like this:

for f in sprites/*.png; do g=$(shasum $f); h=${g:0:7}; b=$(basename $f .png); d=$(dirname $f); echo mv -v $f $d/$b-$h.png; done

You should be able to copy the above line from your browser and paste it into your Terminal session as one single line, with no wrapping.  It's for that reason that I have used the (otherwise horrible) 1-letter variable names.

Where I have "sprites" as the directory name substitute in your own directory name if needed.

Carefully inspect the output of the echo'ed out move commands and if necessary, up-arrow and edit the command until it works the way you like.

Then finally up-arrow, arrow back and remove the "echo" and press enter to execute it for real.

If the command works, then you should see the "mv -v" spit out a line for each file looking like this:

sprites/alarm-clock.png -> sprites/alarm-clock-1dcd66f.png

If you had 10 sprites you should see 10 lines like that you should now be able to check your sprites directory and find a nice list of completely distinctively named files, guaranteed not to collide.

Happy spriting!

Thursday, May 23, 2013

Early Results with Artboard

I've started using Artboard, a fairly simple vector graphics program for the Mac, to do some of my in-game artwork.  Basically I put my room render in as a background so I can get the scale and perspective right, then draw the artwork for the items and props in the room over the top.

I have been using Anime Studio and Manga Studio for this, at various times.  I use Anime Studio as its the vector graphics based animation package that I use for doing my characters, and I need that same look for the in-game items.  Trouble is since its an animation package its not well suited to just doing static graphics.  I therefore was using Manga Studio which is my comic drawing software - it gives lovely pen strokes and cel shading as per Manga comics, but unfortunately the resulting look is not really a match for the vector art that comes from Anime Studio.

Hence I have picked up Artboard, for $35 from the AppStore.  I would have looked at Illustrator but its very expensive and over-featured for what I want.  I also tried Inkscape and that would have been my preference but the performance going through X-Quartz on the Mac was just awful.  On bigger drawings that pen lag was just killing me.  Artboard is a nice combination of features and for price, and has great performance on my laptop.

Here's some of the things I have done with it so far.

Alarm Clock to wake our hero up out of bed

Handy screwdriver

Room render with Artboard drawings on top
It's not perfect, but there is a lot to like here.

I particularly like the expert styles - I used the ability to create copies of the stroke and outset each one to create the sort of "bevelled-in" look on the dial face for the clock.  This stroke was stacked on top of one of Artboards pre-packaged styles, a glossy black which was just right for the face of the clock.

The point editing mode of Artboard is very good too - you can quickly go from shape manipulation mode over to path mode and back again, just by double tapping on the object.  In Inkscape its not so easy to go between treating an object as a path and as a shape.

I have come across a few bugs, but the authors of Artboard - one of whom is an Australian software engineer - seem to be quite responsive, and they're producing new releases so it looks hopeful that these will get dealt with soon.

If you're looking for a simple but relatively powerful and fun graphics editor for your game work I recommend giving Artboard a try.

Wednesday, May 22, 2013

Pro-style Placeholder Image for Chooser Dialogs

I have been busy with my game development so my blog and tut video stream have been a bit quiet.


Meantime here's a quick video tutorial on creating one of those nice "chiselled grey text" placeholder images that make an image chooser dialog in your game or app so much more pro-stylee.




For this sort of job I often use the GIMP which is a great piece of open-source software and for me one that provides all the functionality I need in bit-map graphics for game development.  To get GIMP for the Mac, go here: http://www.gimp.org/downloads/ and click Download GIMP 2.8 to get Simone Karin Lehmann's build - the others I find are often missing stuff and don't work nearly as well on Mac as her builds.

If you work through the tutorial and are looking for more here are some things you can do that will give some extra nice polish to the chiselled text placeholder.

Carefully color match to your dialogs background.


You can try to get the GIMP to produce the same color for its image background as your dialog, but because of the way the map filter works with the "compensate for darkening" not always being accurate, I suggest instead setting up your GIMP image to be as close to the color you want as possible, and then adjust the dialog background color in your UI designer.  On Mac you can use the magnifying glass on the color chooser to pick up the color of the image:



If you're using XCode for example you can navigate to the color chooser for the background color of the dialog, and then click on the magnifying glass and go across into the the Preview app which you have open alongside showing the image with the color you want to match.  Then just click to sample that colour.  Your XCode dialog is now the exact same background color.

Change the Look of your Chiselled Text


Try applying a blur to your black text after you've typed it in, but before you use it as the bump map.  This will cause your chiselled letters to have a more rounded look instead of the straight sides.  Depending on what you want it might look good in your app or game.

You can also play around with the settings in the Bump Map dialog to get different effects.


Get a Smoother Look


If the aliasing and jags on this image are annoying you can get a better result by running through this exercise with everything done twice as big.  So start out with an image that is twice as wide and twice as high as described here, and use a font that is twice as big.

When you have the final result, the scaling down process will nicely smooth out the jaggies.  This produces a better smoothing result than trying to blur the image you have.

Sunday, May 5, 2013

Enabling ARC for your Cocos2D iOS projects

A quick video tutorial on how to enable Automatic Reference Counting for your Cocos2D iOS game projects.  The process is fairly simple, but its not trivial and its easy to get wrong, so I've taken the time out to record how its done in XCode.

I use the technique described by Steffen Itterheim in his book Learn cocos2d Game Development with iOS 5 which I thoroughly recommend if you're getting started with Cocos2D on iOS.

Here's the video.



Here's the why - although I do explain this in the video, you might want to know why you need it before you invest the time.

Cocos2D by default does not build as a seperate library - the Cocos2D templates just inject all the source code as a tree of files right into your new project.  That gets built alongside your own source code right into the same binary target.

Now Cocos2D currently does not support ARC since I guess the project was started before ARC came along and its a big effort to do the conversion while ensuring nothing breaks.  That means that your whole project can't use ARC - so you would have to do all your release and retains and other Objective-C memory management as per the bad old days before automatic reference counting.

To fix it we build Cocos2D as a seperate compilation unit - a static library - and it builds without ARC as before.  But now your game code is seperate and it can have ARC enabled.  Simple idea, and easy enough to do, once you know how.

Hope the video helps and happy game hacking with Cocos2D!

Update:  I just discovered that Steffen has his own video tut on this already.  Maybe you guys will still get some value from my take on this process, so I'll leave my version up for now.

Update 2: If you get a run-time error like this:

-[CCPhysicsSprite setPTMRatio:]: unrecognized selector sent to instance

...then its because you need to do one more step when you enable ARC by making Cocos2D a static library that includes Box2D.  That is to add the macro

CC_ENABLE_BOX2D_INTEGRATION=1

into the Build Settings for the Cocos2D library target.  Here's a screenshot:


Thanks to Komet163B on my YouTube channel for reporting on this issue.

Friday, May 3, 2013

Trimming Transparency Follow-up: Cropping

Just a really quick follow-up to my recent post about trimming your static images.  I got some great thoughtful comments on my G+ account regarding this and it got me thinking - I needed to clarify how you could use this same technique not just for static images but also for animation sprite sheets.

I posted an update section on that recent post, but I'll repeat it here:
Update: I realised that this post could confuse people into thinking that your sprite sheets of animations could be processed this way. This won't work. I know I said these images are coming out of my animation program but that is because they are stills that I use for the various static poses, and since I use AnimeStudio for all my character art I have to get the sprites looking consistent, so that means whether animated or still I need to use the same program.
Why not? When you trim off the transparency close to the colored pixel content that means the position of the character in the frame will change from frame to frame giving a jittery effect. Definitely not what you want for your animations. But for static poses this technique works just fine.
OK - so how could you use ImageMagick to trim your animated sprite frames?  There's two comments to make before we dive into the script I came up with to help with this:

  • First - do you really need to trim them?  TexturePacker makes a good job of ridding yourself of these extra transparent pixels, and if you already have a way of hit-testing that won't be compromised by the extra alpha may not be a problem.  Thanks to +Krzysztof Bielawski for highlighting this.
  • Second - lets use the word crop to refer to the process of cutting off unwanted parts of the image to precise pixel dimensions
    • Trimming refers to getting rid of all alpha transparency regardless of where that happens to be pixel-addressing-wise.
If your game doesn't require hit testing your animated sprites in that way - maybe you just use a simple radius test - then there's no point in worrying about this trimming probably.

If we do decide to go ahead with this lets get terminology right - ImageMagick uses these terms and from my graphics work I follow the same approach.  Trim means cutting away unwanted stuff (no matter what the dimensions) and cropping is like guillotine - once you position the bounds to the pixel that is where the cut falls.

OK - so we're going to crop?  Here is how to do it:

convert my_sprite_0001.png -crop \
    '309x518+65+238' +repage my_sprite_cropped_0001.png

By referring to my recent post, you can find out how to install ImageMagick, and what the "convert" command-line here is doing.  As before the repage is recalculating the page meta-data after the crop command.

What's new is the -crop and the strange expression in quotes.  '309x518+65+238'

The first two numbers (seperated by the "x" character) are the width and height of the area to be cropped out.  This area needs to be as large as the union of the bounding rectangles of all the sprites in your animation sequence.

The second two numbers represent the offset into your source image (my_sprite_0001.png in the above) as an x, y coordinate pair - with the top-left of the image as the origin.

Note that Cocos2D and many other OpenGL based game kits use the bottom-left as the origin - and mathematical co-ordinate systems do this too.  Take a bit of care to make sure this is right.

Wait: what?  Union of the bounding rectangles?  Yup - this just means that whatever rectangle you choose as your crop is going to be the same size and position for every crop operation done on your folder of images.  This means that in order to avoid cutting off any part of one of the animation frames it will need to be equal to all of the rectangles that would have been used in a trim operation, all overlaid over each other - this "rectangle summing" is called the "union".

In practice I found the easiest way to do this is to find a large image, say the "contact pose" - see my early "rushy animation tut" post - and put a box around that with my image editor (I use GiMP, but you might use photoshop) and check the dimensions and offset.

Then I run my crop script using those dimensions, and check the result using Preview - if an image in the sequence got some part cropped off I can open that in my image editor and adjust those dimensions.

Checking the crop by using the Preview program on Mac
Here's an example of the script running, copied straight out of my Terminal session. Just after the script does its processing I run Mac's Preview program on all the images by using the "open" command:

~/Documents/Art/animations sez$ ./cropdir.sh walk-cycle-side-12fps-fresh 309 518 65 238
About to make cropped copies of the files in walk-cycle-side-12fps-fresh and place into walk-cycle-side-12fps-fresh-converted-1367637222
The resulting cropped copies will be 309w x 518h and at offset 65, 238 in
the image.

Continue (y/n) ?  [N]: >Y
   walk-cycle-side-12fps-fresh/walk-side_00001.png    -- cropped to -->   walk-cycle-side-12fps-fresh-converted-1367637222/walk-side_00001.png
   walk-cycle-side-12fps-fresh/walk-side_00003.png    -- cropped to -->   walk-cycle-side-12fps-fresh-converted-1367637222/walk-side_00003.png
   //.... more
   walk-cycle-side-12fps-fresh/walk-side_00047.png    -- cropped to -->   walk-cycle-side-12fps-fresh-converted-1367637222/walk-side_00047.png
   walk-cycle-side-12fps-fresh/walk-side_00049.png    -- cropped to -->   walk-cycle-side-12fps-fresh-converted-1367637222/walk-side_00049.png
~/Documents/Art/animations sez$ 
~/Documents/Art/animations sez$ open walk-cycle-side-12fps-fresh-converted-1367637222/*

And this is a complete listing of the script I use. As before - caveat emptor, backup before use, all care, no responsibility.

#!/bin/bash

# Copyright Sarah Smith - http://indiegamecodingconfessions.blogspot.com

# ImageMagick is from http://www.imagemagick.org

# This script is placed in the public domain - feel free to use it how you
# want, though a link to this blog would be nice.  :-)

if [ $# != 5 ]; then
    echo "Usage: $0 <dirname> <width> <height> <x-offset> <y-offset>"
    exit 1
fi

# Halt execution the second a command fails
set -e

# Uncomment this line to get debugging info
# set -x

UNIQ_NM=$(date "+%s")
DESTDIR="$1-converted-$UNIQ_NM"

echo "About to make cropped copies of the files in $1 and place into $DESTDIR"
echo "The resulting cropped copies will be $2w x $3h and at offset $4, $5 in"
echo "the image."
echo ""
echo -n "Continue (y/n) ?  [N]: >"

read goahead

if [ "x$goahead"="xy" -o "x$goahead"="xY" ]; then

    mkdir $DESTDIR
    GEOMETRY="$2x$3+$4+$5"

    for fn in $1/*; do
        DESTNAME=$DESTDIR/$(basename $fn)
        convert $fn -crop $GEOMETRY +repage $DESTNAME
        echo "   $fn    -- cropped to -->   $DESTNAME"
    done

fi

And you can download this script from my Dropbox.  As in my previous post, just chmod it to executable and run it from the command line as above.

Happy image hacking!

Thursday, May 2, 2013

Trimming Transparency from Images

When you export images from some programs, you wind up in some cases with the actual content as a small area of coloured pixels in a sea of alpha transparent nothing.

This happens to me when I'm animating my character around and I'm doing so against a background that is say 1024x768 where the actual character's image is a tiny percentage of that size.

A 1024x768 png from my animation program
This is completely to be expected - the designers of your other programs always have to assume that your export is intended to be the size of your original canvas; but when you have dozens or maybe even hundreds of frames of animation all with wasted transparent pixels, removing it all by hand using GiMP or Photoshop is agonizing.

When you're using TexturePacker or ZwopTex your transparent pixels are probably removed nicely for you when the sprites are stored, but still they can mess up your hit testing and on-screen positioning for your game.

The image content I want with extra transparent pixels cropped away
Here is a way to crop those transparent pixels automatically in large batches, and the program to do it is free.

OK, this is what you need - the ImageMagick program from ImageMagick.org - a fantastic and very powerful set of command line tools.

I'm on MacOSX Mountain Lion and found this great installer which the guys at Cactus Labs have put together - it was just case of clicking through and it all just worked!

Once you have ImageMagick installed check that it is working by opening up a command line - on MacOSX, just do <command>-<space> to access Spotlight and type "Term" and you should be able to hit enter on the first match to get the Terminal.app program running.  Then at the command prompt type:   convert -version


~/MyArtWork sez$ convert -version
Version: ImageMagick 6.8.4-8 2013-04-08 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2013 ImageMagick Studio LLC
Features: DPC OpenMP
Delegates: bzlib jng jp2 jpeg lcms png tiff xml zlib

That shows that the ImageMagick command line tool called "convert" is up and running. The script I'm about to show you won't work if this command is not available.  If you had a Terminal running when you installed ImageMagick you may need to close and re-open it to get this to work.

Now the basic technique is to use two commands that convert knows about:
From the command line the trim command looks like this:

convert my_image.png -trim +repage my_image_trimmed.png

The trim command is what does all the work - it samples the image at the corners and assumes those pixels are what the background of your image is.  Then it crops in the image as small as it can on all four sides - providing that the only pixels it is throwing away are that background color it sampled.  It works with all colours of background, not just alpha transparent (which ImageMagick calls the colour name "none").

Now there's a trick here - what if one some of your frames the sprite just happens to be touching in the corner where the sample is made?  Oops - that will mess up ImageMagick's trim!  To counter this problem, first we add a border of transparent pixels around the image so that when it comes time to run the trim, we can be sure no valuable pixels will get sampled by mistake.  That is where the border command to convert comes in.

The whole script looks like this:
!/bin/bash

# Copyright Sarah Smith
# http://indiegamecodingconfessions.blogspot.com
# ImageMagick is from http://www.imagemagick.org
# Back up your work before running this script!
# This script is placed in the public domain
# Feel free to use it how you want, though a 
# link to this blog would be nice.  :-)

if [ $# != 1 ]; then
    echo "Usage: $0 <dirname>"
    exit 1
fi

# Halt execution the second a command fails
set -e

# Uncomment this line to get debugging info
# set -x

UNIQ_NM=$(date "+%s")
DESTDIR="$1-converted-$UNIQ_NM"
mkdir $DESTDIR

for fn in $1/*; do
    TMPDESTNAME=$DESTDIR/tmp-$(basename $fn)
    DESTNAME=$DESTDIR/$(basename $fn)
    convert $fn -bordercolor none -border 3x3 $TMPDESTNAME
    convert $TMPDESTNAME -trim +repage $DESTNAME
    rm -f $TMPDESTNAME
    echo "   $fn    -- trimmed to -->   $DESTNAME"
done

How to use the script.
  • First save all your work somewhere, make sure its backed up!
  • In a terminal, cd into the directory where your artwork is
    • you backed up this directory didn't you?
  • Download the script trimdir.sh as a file to your computer.  Try this drop box link.
    • save it into that same directory where your art is
  • Make the script executable, and run it like this:
~/Documents/my_art$ trimdir.sh my_directory_of_sprites

...where "my_directory_of_sprites" is the name of a directory containing sprites you want to trim.  The script will create an output directory and put the trimmed versions of all the files in there.

Word of warning - this script is just my own hacking so use at your own risk - and back up before you start!  See my earlier post about backups!  The script tries to avoid doing anything destructive, and never replaces the files you specify, only placing the cropped versions into a new directory.  But like all scripts with great power comes great responsibility!

Also click the topic label "command line" below for more posts about the command line, or search for tutorials on it on the web if you're not comfortable with the command line or Terminal usage.

Here's an example of me running the script on a directory called "static-poses":

~/Documents/AG-Art/erin-animations sez$ ./trimdir.sh static-poses

   static-poses/back-quarter.png    -- trimmed to -->   static-poses-converted-1367477342/back-quarter.png

   static-poses/back.png    -- trimmed to -->   static-poses-converted-1367477342/back.png

   static-poses/front-quarter.png    -- trimmed to -->   static-poses-converted-1367477342/front-quarter.png

   static-poses/front.png    -- trimmed to -->   static-poses-converted-1367477342/front.png

   static-poses/side.png    -- trimmed to -->   static-poses-converted-1367477342/side.png

Of course ImageMagick is capable of so much more than this. Please let me know if you use this technique, or my script and how it worked out for you. Have fun hacking your sprites!

Update:  I realised that this post could confuse people into thinking that your sprite sheets of animations could be processed  this way.  This won't work.  I know I said these images are coming out of my animation program but that is because they are stills that I use for the various static poses, and since I use AnimeStudio for all my character art I have to get the sprites looking consistent, so that means whether animated or still I need to use the same program.

Why not?  When you trim off the transparency close to the colored pixel content that means the position of the character in the frame will change from frame to frame giving a jittery effect.  Definitely not what you want for your animations.  But for static poses this technique works just fine.