家で自分のシンプルな二次元のゲームを制作していて、色々のイメージが必要でした。フォトショップで作った後の上に全部の部分を一つずっつ切り取りして、別々のファイルに保存して、レイヤーをなくして、コピーして元のファイルに取り付けて、取った場所に合わせて、その位置の値をソースに書かなければならなりませんでした。
イメージ10枚だけでも45分ぐらい掛かってしまいました。
もっといい方法があるはずと思った。ずいぶん前からフォトショップは外側のスクリプト言語で動かせることがあったけど、実はCS版まであまり便利じゃありませんでした。CS版のスクリプト言語を調べてからこのスクリプトを出来いました。
それは自動的にレイヤーを切り取りして、別々のファイルに保存して、位置のデータをC/C++で使いやすい形に保存するスクリプトです。
「Crowhunt」という簡単な二次元ゲームを作ろうとしてください。そのためにこのようなイメージが必要です。烏(crow)、羽(feather)、十字線(crosshair)、銃(handgun)、タイトル(title)、そして背景(background)。
作ったスクリプトの動きはレイヤーとグループの最初段階を一つずっつそのレイヤーのサイズに切り取りして、別のファイルに保存することです。
そのレイヤーとグループの名前で別のファイルに保存します。
もう一つ私に必要な機能はある点をしてして後で参照することです。ほとんど回転とか拡大の原点のためです。今までそのために
フォトショップのカーソルをその点の上に載せて、情報パレットでその点の位置値をみて、手動でソースに書いたけど、それはほんとうに面倒臭いでした。今はグループを作って、参照点が必要のレイヤーをそのグループに入れて、そのグループの中に「rotpoint」という新しいレイヤーを作って、
鉛筆道具で一つのピクセルを描きます。そしたらこのスクリプトはそのピクセルの配置値を保存してくれます。右にある図を見たら銃(handgun)のグループに「rotpoint」のレイヤーがあって、よく見ると一つの黄色いピクセルがあります。
そのピクセルは「handgun」というイメージファイルに保存されてこないけど位置情報をC++のファイルに保存されてきます。
その上レイヤーを統合したくなくて、フォトショップのレイヤーエフェクトを使えるようにしたいでした。フォトショップのことを知っている方は右にあるレイヤーに「crosshair」のレイヤーはベクトルレイヤーになって、「title」はテクストレイヤーになって、両方にレイヤーエフェクトを適用していることを気が付きます。このスクリプトそのままエフェクト含めてファイルを吐き出せます。
イメージを描いて、保存して、スクリプトを起動してます。終わったらレイヤーとグループごとにそのレイヤーの最小サイズにフォトショップのファイルをおいてあります
これは上のファイルの自動的に取り抜かれたイメージファイルです
「handgun」のイメージをよく見たら思ったより大きいです。フォトショップにイメージを取り付けたら全部ファイル入ります。後で移動したければ便利な機能です。
でもこの場合は画面以外の部分が要らないので全部選択して(選択⇒全て)、イメージ⇒取り抜きします。全て選択されていったのでなにも変わらない見えるけど実は画面以外の部分を削除しました。
スクリプトをも一回起動して、「handgun」は完璧に出て来ました。
このファイルも吐き出されてきました
#define CUT_ALLPARTS \
SPRITEINFO(0,HANDGUN,"handgun.psd",120,285,121,286,70,214,184,300) \
SPRITEINFO(1,CROSSHAIR,"crosshair.psd",178,114,348,284,178,114,348,284) \
SPRITEINFO(2,TITLE,"title.psd",15,15,389,112,15,15,389,112) \
SPRITEINFO(3,CROW,"crow.psd",52,101,139,247,52,101,139,247) \
SPRITEINFO(4,FEATHER,"feather.psd",160,128,171,183,160,128,171,183) \
SPRITEINFO(5,BACKGROUND,"background.psd",0,0,400,300,0,0,400,300) \
マクロの引数はこの順番です。最初は指標で、次はIDとファイル名です。次の4つの数字は「rotpoint」の寸法です。「rotpoint」がなければイメージの寸法になります。
その形式は左、上、右、下、で右と下は寸法以上一ピクセルになっています。つまりイメージの幅は(右 - 左)です。(右 - 左) - 1でわない。
その情報をゲームで使いたければこのように使えます。
#undef SPRITEINFO
#include "cut_allparts.psd.info.cpp"
#undef SPRITEINFO
#define
SPRITEINFO(ndx,id,fname,rotleft,rottop,rotright,rotbtm,left,top,right,btm) \
IMAGEID_ ## id,
enum ImageIds
{
CUT_ALLPARTS
IMAGEID_last,
};
struct ImageInfo
{
const char* filename;
int xPos;
int yPos;
int width;
int height;
int centerX;
int centerY;
};
#undef SPRITEINFO
#define SPRITEINFO( \
id, \
label, \
filename, \
centerLeft, \
centerTop, \
centerRight, \
centerBottom, \
cutLeft, \
cutTop, \
cutRight, \
cutBottom) \
{ _T("media/images/") _T(filename), \
(centerRight + centerLeft) / 2, \
(centerBottom + centerTop) / 2, \
cutRight - cutLeft, \
cutBottom - cutTop, \
(centerRight + centerLeft) / 2 - cutLeft, \
(centerBottom + centerTop) / 2 - cutTop, \
},
ImageInfo ImageTable[] =
{
CUT_ALLPARTS
};
Unfortunately, I know very few engines that can directly load Photoshop files. For my purposes I needed targa (.TGA) files. While it *should* be possible to get Photoshop to save targas the problem is I wanted alpha channels as well and I wanted them to have alpha that included the layer effects from
Photoshop.
That's not trivial in Photoshop. The steps are something like:
- create a new empty layer
- merge the visible layers. This will remove the effects and bake them into
the image.
- select the transparency of the layer
- set the background color to black and the foreground color to white
- go to the channel palette and create a new channel
- fill the selection with white
You'd now have the correct alpha. Unfortunately those steps are not easily
accessible from scripting in Photoshop. While it would be possible, under the
current script engine it requires using actions. I tried it once, Photoshop
comes with a "ScriptListener" which will save all everything you do in Photoshop
to a script which you can then edit later. I tried it but it was not easy to
understand and as I already had a different solution that worked I decided to
use that instead.
My different solution is a tool that is part of the
libraries I use for games development written back in 1995
that will load Photoshop files and save them as
targas (among other things). Photoshop by default saves a preview image inside
its files that is the result off all the layers together as well as the
transparency so converting that to a targa through my old tools gives me exactly
what I need.
Here you can see the result. You can see the glow around the title and the
shadow and border around the crosshair as well as the correct alpha for each of
them.
To use the Photoshop cutsprite script manually you'll need at least Photoshop
CS. Make a Photoshop file following the rules described above with each image in
a layer or group and give a name to each layer or group. Save it. Then, Pick
File->Scripts->Browse... from the menus and choose openandcutsprites.jsx.
An open file dialog will appear. Select the file you saved. The script will then
follow these steps
- load the file
- separate each layer and group to a new file and save it to the same folder
as the original based on the name of the layer or group.
- write out a <filename>.info.cpp file with in info about the sizes of the
images.
- close the original image.
Warning: There is NO check for overwriting files so be
careful!
I also wrote a script that will go through a tree of folders finding any Photoshop file that begins with "cut_" and will cut that file automatically. To run that you'll need to install
ActivePerl (free). I could have written
the script in VBScript or JScript but I'm far more comfortable with Perl so I
did it there. Perl supports Microsoft's "Windows
Scripting Host" which is basically a way for any language to be used as a
scripting language for Windows. Microsoft supplies VBScript and JScript. There
is also PerlScript and PythonScript.
The script will start from the current folder and look in every subfolder for
any file that starts with "cut_" and ends in ".psd". If it sees such a file it
will tell Photoshop to run the script above on that file. The easiest way to use
it is just to copy it and the rest of the files to the base folder of whatever
project you are working on. Double click on cutallsprites.wsf and it
should run. Oh, before you do that you should open a command line and type
cscript //H:CScript
capitalization is important! This will set Windows Script Host to default to
using the command line version.
Also included is another Perl program called processPSDtoTGA.pl. This program
will walk all the folders from the current folder down and any ".PSD" file it
finds it will create a corresponding ".TGA" file. Like the previous tool it's
easiest if you just copy this and all the other files to the base folder of your
current project and double click it to run it.
I hope you find this useful. The code is released under a BSD license so feel free to modify any of these to
suit your own needs. You can download it from the link below
cutsprites.1.4.zip
(666k)
Maya Support
I added a Maya Ascii scene file generator to the cutallsprites.wsf
script so once the Photoshop file has been cut you'll find a ".ma" maya ascii file there. Load it up in Maya and it should reproduce the
original setup along with points of origin in the correct spots.
Often many 3d engines have limited 2d abilities. They'll have a full on
animated textures, materials, translation, rotation and scale for 3d but nothing
for 2d. Well, just setup an orthographic camera and use your 3d engine for your
2d. Much simpler than writing a completely new system.
Version History:
- 1.3 - 2006/03/10
- Added "bg_color" layer support. Layers with the name "bg_color" will be turned on if they exist. You can put them inside groups to make them apply to only one group and you can have more than 1.
What's the point?
Well, for many 3D hardware if you want to display a colored texture with transparency you basically need to draw in full color in the color layer and just set the alpha for transparency. In other words, lets say you wanted to have the word "Start" in red. If you just draw it in red with no "bg_color" layer you will get a texture with red pixels on a white background and the correct alpha channel. The problem is the pixels that are anti-aliased at the edges already have white mixed in them. If you use this on some 3D hardware your word will have a slighty white border. To fix this create a layer, name it "bg_color" and fill it with red. Since it's probably confusing hide the layer. Now run the script and you'll get a completely red texture but with the correct alpha. This will look correct on hardware that had issue with the previous texture. See the included sample "cut_bgexample.psd".
- Added support for global "cropsize" layers. Now you can put multiple layers and crop them all to the same size. See the included sample "cut_bgexample.psd".
- Added forcing to a even number of pixels. This should probably be an option since your tools might not have an even pixel limit but 1 extra pixels is not going to bother most people so I decided not to add an option. If you don't like it edit the code.
- 1.2 - 2006/03/04
- Added maya ascii scene generator
- Moved targa generation to photoshop script
- Added black blending / premult for alpha if targa
- 1.1 - 2006/02/17
- Similar to the "rotpoint" layer, added a check for "cropsize" inside a group.
If found the group will be cropped to the size of the "cropsize" layer.