FLAGSTONE Transform SWFをいじってみる。

mixiでゲームを作ってるわけですが、無料、マルチプラットフォームな環境でゲーム作りたいという話で、D言語で作りたかったのだけど、仕事でも役に立つ言語がいいって話で、JavaFlash外いって話で作っております。


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

とやってあげますと、データが読み込まれて表示され、音楽も鳴ります。
バンザーイ。