FLAGSTONE Transform SWFをいじってみる。
mixiでゲームを作ってるわけですが、無料、マルチプラットフォームな環境でゲーム作りたいという話で、D言語で作りたかったのだけど、仕事でも役に立つ言語がいいって話で、Java、Flash外いって話で作っております。
mtascは便利なんだけど、画像データや、音声データをリソースとして読み込むことができない。いや、swfファイルにアクションスクリプトを流し込むことはできるので、swfファイルをリソースとして読むことが出来ると考えたほうが良いのかもしれない。しかし、画像データや、音声データから、swfファイルを生成する機能が無いってことで、リソースコンパイラ的なものが欲しくて、FLAGSTONE、JavaSWF2ってのを使ってます。Java用のmingってところの存在です。mingはpng読み込んでくれないんだよなぁ。
FLAGSTONE Transform SWF
http://www.flagstonesoftware.com/downloads/index.html
ライセンスに疎いんでなんとなく、FLAGSTONEってのを使ってリソースコンパイルは作れました。でも、開発者用ならBSD-Licenceだかなんだかってことらしいので、いいのかなぁ?まぁいいや。
ろくなもんじゃないんだけど、
// mk01.java import com.flagstone.transform.*; import com.flagstone.transform.util.*; import java.io.*; import java.util.*; public class mk01 { public static FSDefineMovieClip createImageSprite(FSMovie movie, String src, int mode) throws Exception { // image FSImageConstructor imageGenerator = new FSImageConstructor(src); int imageId = movie.newIdentifier(); byte by = imageGenerator.getColorImage(); int w = imageGenerator.getWidth(); int h = imageGenerator.getHeight(); int f = imageGenerator.getFormat(); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { int r = by[y][x][0] & 0xff; int g = by[y][x][1] & 0xff; int b = by[y][x][2] & 0xff; int a = by[y][x][3] & 0xff; switch (mode) { case 0: r = r * a / 255; g = g * a / 255; b = b * a / 255; break; case 1: a = 0; break; case 2: int l = r + g + b; // 明るさから、半透明度を求める。 a = l / 3; //aは0〜255だと。 int m = Math.max(r, Math.max(b, g)); // mが255になるようにする。 255 / m r = r * a / m; g = g * a / m; b = b * a / m; break; } by[y][x][0] = (byte)r; by[y][x][1] = (byte)g; by[y][x][2] = (byte)b; by[y][x][3] = (byte)a; } } imageGenerator.setColorImage(f, w, h, by); FSDefineObject image = imageGenerator.defineImage(imageId); movie.add(image); // shape int shapeId = movie.newIdentifier(); FSDefineShape3 shape = imageGenerator.defineEnclosingShape(shapeId, imageId, 0, 0, new FSSolidLine(0, new FSColor(0,0,0,0))); movie.add(shape); // clipMovie(sprite)を作成 ArrayList clipMovements = new ArrayList(); clipMovements.add(new FSPlaceObject2(shapeId, 1, 0, 0)); clipMovements.add(new FSShowFrame()); FSDefineMovieClip clip1 = new FSDefineMovieClip(movie.newIdentifier(), clipMovements); movie.add(clip1); movie.add(new FSExport(clip1.getIdentifier(), src)); return clip1; } public static void createSound(FSMovie movie, String src) throws Exception { int soundId = movie.newIdentifier(); // sound FSSoundConstructor soundGenerator = new FSSoundConstructor(src); movie.add(soundGenerator.defineSound(soundId)); movie.add(new FSExport(soundId, src)); } public static void main(String args) throws Exception { FSMovie movie = new FSMovie(); movie.setFrameRate(30); movie.setFrameSize(new FSBounds(0, 0, 640 * 20, 480 * 20)); movie.add(new FSSetBackgroundColor(new FSColor(0xff, 0xff, 0xff))); for (int i = 1; i < args.length; i++) { String name = args[i]; System.out.println(name); try { int mode = 0; if (name.length() > 4 && name.substring(0, 4).equals("aimg")) { mode = 1; } if (name.length() > 4 && name.substring(0, 4).equals("bimg")) { mode = 2; } createImageSprite(movie, name, mode); } catch (Exception e) { createSound(movie, name); } } movie.add(new FSShowFrame()); movie.setSignature("FWS"); movie.encodeToFile(args[0]); } }
FLAGSTONEを使ったリソースコンパイラのソースです。
コンパイルは、transform.jar,transform-util.jarに適当にクラスパス通しておいて、
javac mk01.java
使い方は、
java mk01 outswf filename1 filename2 ...
です。
outswfには出力するswfファイルの名前を、
filename1〜nにはjpg,bmp,png,mp3が使えるはず。
aimgってディレクトリに画像データを入れとくと、加算演算用データを生成、bimgってディレクトリに画像データを入れとくと、加算合成もどきの半透明合成をやるデータを作ります。何かいてるかきっとわからんなこりゃ。
例えば
java mk01 mk01.swf img/background.png sound/a.mp3
とすると、mk01.swfができます。
これだけだと、なんも表示されないし、音楽もなりません。
しかし、
// Main.as class Main { public function Main() {} public static function main() { var bg = _root.attachMovie("img/background.png","bg", 0); var music = new Sound(); music.attachSound("sound/a.mp3"); music.start(0, 999); music.setVolume(100); } }
上のようなアクションスクリプトを書きまして、
mtasc -main Main.as -swf mk.swf
とやってあげますと、データが読み込まれて表示され、音楽も鳴ります。
バンザーイ。