2013/09/04(水) [n年前の日記]
#1 [haxe] HaxeFlixelTiledでハマり中
HaxeFlixel で、マップデータファイル、.tmx を読み取れるらしい、
_crazysam/HaxeFlixelTiled - GitHub
というソースがあるわけだけど。使い方というか、組み込み方が分からなくてハマっていたり。
FlashDevelop 上で、import org.flixel.tmx.TmxMap; を書いても、「そんなクラスは見つからねえよ」と言われ続けて、一体どこに置けばいいんだろうと。
src/org/flixel/tmx/ となるように置けばよかったらしい。ファイルの配置としてはこんな感じ。
しかし今度は、TmxMap.hx 内等で、「Hash は削除されたよ。Map 使え」と言われて。Haxe 2 から Haxe 3 になった際に、言語仕様が変わったらしい。
_Haxe 2 から 3 へ - rfなブログ
_Haxe 3 Migration - Haxe
しかし最後は、ビルド中にエラーが。
Hash と Map の件でエラーが出たあたり、件のライブラリ?は、Haxe 3 や OpenFL に対応していない、最新の Haxe や OpenFL に合わせてメンテナンスされてない、ということだよなと…。これ以上試してみても、無駄に終わりそうな気がしてきた。
_lib.haxe.org - tmx というライブラリもあるらしいのだけど。こちらは、使用例・サンプルがどこにも見つからず。ソースを眺めた感じでは、.tmx を解析して、各変数に各値を代入・記録してるように見えたけど…。.tmx は、xml、base64、csv等、色々な形式でレイヤー情報を持っているのだけど、それぞれにちゃんと対応して解析しているように見えた。至れり尽くせりなライブラリっぽいけど、使い方が分からんのではなあ…。
FlashDevelop 上で、import org.flixel.tmx.TmxMap; を書いても、「そんなクラスは見つからねえよ」と言われ続けて、一体どこに置けばいいんだろうと。
src/org/flixel/tmx/ となるように置けばよかったらしい。ファイルの配置としてはこんな感じ。
. │ Sample2.hxproj │ Sample2.xml │ └─source │ Gbl.hx │ Main.hx │ MenuState.hx │ Player.hx │ ProjectClass.hx │ Reg.hx │ Stage1.hx │ └─org <---- ココ └─flixel └─tmx TmxLayer.hx TmxMap.hx TmxObject.hx TmxObjectGroup.hx TmxPropertySet.hx TmxTileSet.hx
しかし今度は、TmxMap.hx 内等で、「Hash は削除されたよ。Map 使え」と言われて。Haxe 2 から Haxe 3 になった際に、言語仕様が変わったらしい。
_Haxe 2 から 3 へ - rfなブログ
_Haxe 3 Migration - Haxe
Code example:仕方ないので、サンプルを参考にしつつ修正。
// haxe 2
var hash = new Hash();
var intHash = new IntHash();
var typedHash : Hash<MyClass>;
// haxe 3
var hash = new Map();
var intHash = new Map();
var typedHash : Map<String,MyClass>;
hash.set("foo", 1);
intHash.set(1, 2);
しかし最後は、ビルド中にエラーが。
source/org/flixel/tmx/TmxTileSet.hx:87: lines 87-95 : Please use set_image to name your property access method source/org/flixel/tmx/TmxTileSet.hx:83: lines 83-86 : Please use get_image to name your property access method一体何を怒られてるのか分からない…。
Hash と Map の件でエラーが出たあたり、件のライブラリ?は、Haxe 3 や OpenFL に対応していない、最新の Haxe や OpenFL に合わせてメンテナンスされてない、ということだよなと…。これ以上試してみても、無駄に終わりそうな気がしてきた。
_lib.haxe.org - tmx というライブラリもあるらしいのだけど。こちらは、使用例・サンプルがどこにも見つからず。ソースを眺めた感じでは、.tmx を解析して、各変数に各値を代入・記録してるように見えたけど…。.tmx は、xml、base64、csv等、色々な形式でレイヤー情報を持っているのだけど、それぞれにちゃんと対応して解析しているように見えた。至れり尽くせりなライブラリっぽいけど、使い方が分からんのではなあ…。
◎ 結局、jsonを読み込んでどうにかした。 :
Tiled Map Editor は、json でエクスポートもできるので、それでどうにかすることにした。.tmx を直接読むのは諦める。
以下、Haxe 3 L OpenFL 用のソース。
application.xml に、以下の指定を追加。
Tiled が出力した json の文字列の中から、必要なところだけ取り出すためのクラスを作成。 src/ フォルダの中に、TmxJson.hx というファイル名で作成した。
TmxJson.hx
使いたいファイルの中に、記述を追加。
ハマるかと思ったけど、そうでもなかった。結構あっさりBGが表示された。
コレ、DXRuby あたりも、同じやり方でできそうだなと思えてきたり。Ruby にも、json を扱うための何かがあったような気もするし。とりあえず、マップデータを json で出力できれば、後はどうにでもなりそうな。
以下、Haxe 3 L OpenFL 用のソース。
application.xml に、以下の指定を追加。
<assets path="assets/maps" rename="maps" /> <assets path="assets/maps" include="*.tmx" type="text" /> <assets path="assets/maps" include="*.csv" type="text" /> <assets path="assets/maps" include="*.json" type="text" />
- assets/maps/ フォルダを、プログラム中からは "maps/" として扱えるようにリネーム扱いにしてる。
- .tmx、.csv、.json ファイルは、テキストファイルとして扱え、と指定をしている。
Tiled が出力した json の文字列の中から、必要なところだけ取り出すためのクラスを作成。 src/ フォルダの中に、TmxJson.hx というファイル名で作成した。
TmxJson.hx
package ; import haxe.Json; /** * Tiled Map Editor で export した json を解析 * @author mieki256 */ class TmxJson { public var width:Int; public var height:Int; public var bgcolor:Int; public var layerTileData:Map<String,String>; public var layerWidth:Map<String,Int>; public var layerHeight:Map<String,Int>; public function new(jsondata:String) { // jsonを解析 var d = Json.parse(jsondata); // タイルの縦横個数を取得 width = Std.parseInt(d.width); height = Std.parseInt(d.height); // 背景色を取得 var s:String = untyped d.backgroundcolor; s = "0x" + StringTools.replace(s, "#", ""); bgcolor = Std.parseInt(s); layerTileData = new Map(); layerWidth = new Map(); layerHeight = new Map(); // 各レイヤーのタイル並び情報を取得 var layernum:Int = Std.parseInt(d.layers.length); for (i in 0...layernum) { var name:String = untyped d.layers[i].name; // レイヤーの縦横タイル個数を取得 var w:Int = Std.parseInt(untyped d.layers[i].width); var h:Int = Std.parseInt(untyped d.layers[i].height); layerWidth.set(name, w); layerHeight.set(name, w); // タイル並びを整形 var tiledata:Array<Int> = untyped d.layers[i].data; var count = 0; var layer:String = ""; for (y in 0...h) { var row = new Array(); for (x in 0...w) { var c:Int = Std.parseInt(untyped tiledata[count]); // Tiledのデータは、 // 0番が透明、1番からチップ番号が始まるので、 // 若干番号を調整する。 if ( c > 0 ) c -= 1; row.push(c); count++; } layer += row.join(",") + "\n"; } layerTileData.set(name, layer); } } // 与えられたレイヤー名のタイル並びを返す public function getLayer(layerName:String):String { return layerTileData.get(layerName); } }
使いたいファイルの中に、記述を追加。
import org.flixel.FlxTilemap; import flash.display.BitmapData; import flash.Lib; import openfl.Assets; import TmxJson;
// BGを生成 var mapimg:BitmapData = Assets.getBitmapData("maps/area01_level_tiles.png"); var mapdata:String = Assets.getText("maps/level1.json"); var mapcsv:TmxJson = new TmxJson(mapdata); bg_a = new FlxTilemap(); bg_a.loadMap(mapcsv.getLayer("layer1"), mapimg, 16, 16, FlxTilemap.OFF); bg_a.solid = false; // アタリなしを指定 add(bg_a);
- Assets.getText("maps/level1.json"); で、jsonファイルの中身を文字列として取得している。
- new TmxJson(mapdata); で、json文字列の中から、マップレイヤーのタイルの並びデータ等を解析・記録。
- mapcsv.getLayer("layer1") で、"layer1" という名前をつけたレイヤーの、タイルの並びデータを csv的な文字列の形で得られる。
ハマるかと思ったけど、そうでもなかった。結構あっさりBGが表示された。
コレ、DXRuby あたりも、同じやり方でできそうだなと思えてきたり。Ruby にも、json を扱うための何かがあったような気もするし。とりあえず、マップデータを json で出力できれば、後はどうにでもなりそうな。
◎ 20013/09/10追記。 :
上の TmxJson.hx はバグってることが分かった。
- Tiled上で背景色を指定していないデータを作った場合、TmxJson.hx を通すと止まってしまう。bgcolor 関係の部分は全部削除しといたほうが良さそう。どうせ背景色なんか使わないだろうし…。
- Std.parseInt() を使って、文字列を数値化しようとしている部分は、html5 で出力した場合におかしな動作になる。
[ ツッコむ ]
以上です。