[GameMaker: Studio] AutoTileGenのタイルを簡単に設置する

AutoTileGenでタイルを作成して、それを実際にTiled等でマップ化するときに、このように配置によって適切なタイルを選択しながら置いていくのは結構な根気と時間が必要です(Tiledであればrules.txtを作成することで下記と同じような自動化ができます)

gms_tileindex_autoset_1gms_tileindex_autoset_2

上に重ねる装飾はともかく、このような地形のみのデータ作りに関しては、もっとシンプルに“0”“1”かで配置できれば作業はぐっと楽になります。

gms_tileindex_autoset_3

そのためには配置位置の周辺のどこに他のタイルがあるかによって中心とするタイルのインデックスをプログラムで自動的に変えてあげればよいのですが、その判定を計算のみで行うとちょっと面倒です。

四角形の場合、周囲には8ブロックあり、それを“0”“1”かで判断するならばその組み合わせは全部で256通りしかありません。
ならばその256通りを予めデータとして作っておけば大幅に処理が簡略化できそうです。

012
3*4
567

まず、この0から7の順でタイルが“無=0”“有=1”かを並べて8ビットの2進数として、それを10進数に変換します。

010
0*1
110

この組み合わせなら0100111078になります。この78ならタイルのimage_indexは何になる?といった感じです。
この256通りの組み合わせを実際にデータ化するとこうなります。

var local_autotilechange_data_src = "[" + "11,0,15,0,43,0,47,0,139,0,143,0,171,0,175,0,31,1,63,1,159,1,191,1,22,2,23,2,54,2,55,2," + "150,2,151,2,182,2,183,2,2,3,3,3,6,3,7,3,34,3,35,3,38,3,39,3,130,3,131,3,134,3,135,3," + "162,3,163,3,166,3,167,3,219,4,10,5,14,5,42,5,46,5,138,5,142,5,170,5,174,5,26,6,58,6,154,6," + "186,6,18,7,19,7,50,7,51,7,146,7,147,7,178,7,179,7,107,8,111,8,235,8,239,8,255,9,214,10,215,10," + "246,10,247,10,66,11,67,11,70,11,71,11,98,11,99,11,102,11,103,11,194,11,195,11,198,11,199,11,226,11,227,11," + "230,11,231,11,126,12,74,13,78,13,202,13,206,13,90,14,82,15,83,15,114,15,115,15,104,16,105,16,108,16,109,16," + "232,16,233,16,236,16,237,16,248,17,249,17,252,17,253,17,208,18,209,18,212,18,213,18,240,18,241,18,244,18,245,18," + "64,19,65,19,68,19,69,19,96,19,97,19,100,19,101,19,192,19,193,19,196,19,197,19,224,19,225,19,228,19,229,19," + "72,21,73,21,76,21,77,21,200,21,201,21,204,21,205,21,88,22,89,22,92,22,93,22,80,23,81,23,84,23,85,23," + "112,23,113,23,116,23,117,23,8,24,9,24,12,24,13,24,40,24,41,24,44,24,45,24,136,24,137,24,140,24,141,24," + "168,24,169,24,172,24,173,24,24,25,25,25,28,25,29,25,56,25,57,25,60,25,61,25,152,25,153,25,156,25,157,25," + "184,25,185,25,188,25,189,25,16,26,17,26,20,26,21,26,48,26,49,26,52,26,53,26,144,26,145,26,148,26,149,26," + "176,26,177,26,180,26,181,26,0,27,1,27,4,27,5,27,32,27,33,27,36,27,37,27,128,27,129,27,132,27,133,27," + "160,27,161,27,164,27,165,27,123,28,95,29,222,30,250,31,254,32,251,33,30,34,62,34,158,34,190,34,210,35,211,35," + "242,35,243,35,106,36,110,36,234,36,238,36,27,37,59,37,155,37,187,37,218,38,122,39,223,40,127,41,75,42,79,42," + "203,42,207,42,120,43,121,43,124,43,125,43,216,44,217,44,220,44,221,44,86,45,87,45,118,45,119,45,94,46,91,47" + "]";

JSON形式で、偶数番が周囲のブロックの情報、奇数番がimage_indexの値です。
このデータを使いやすいようにds_priority化します。この変換は起動時に一度だけで大丈夫です。

var local_autotilechange_data_list = -1; var local_autotilechange_data_json = json_decode(local_autotilechange_data_src); if(ds_exists(local_autotilechange_data_json, ds_type_list)) { local_autotilechange_data_list = local_autotilechange_data_json; } else if(ds_exists(local_autotilechange_data_json, ds_type_map)) { local_autotilechange_data_list = ds_map_find_value(local_autotilechange_data_json, "default"); } else { show_debug_message("data_json type error!"); } var local_lp = 0; var local_lpn = ds_list_size(local_autotilechange_data_list); global.autotilechange_data = ds_priority_create(); while(local_lp < local_lpn) { ds_priority_add(global.autotilechange_data, ds_list_find_value(local_autotilechange_data_list, local_lp), ds_list_find_value(local_autotilechange_data_list, local_lp + 1)); local_lp += 2; } ds_list_destroy(local_autotilechange_data_json); ds_map_destroy(local_autotilechange_data_list);

これで以降はglobal.autotilechange_dataでアクセスできます。

あとはタイルを配置するときに先の例のように周囲のタイルを一度2進数文字列にしてそれを10進数に変換して、ds_priority_find_priority(global.autotilechange_data, 10進数にした情報);image_indexに設定すべき値が取得できます。

これを実際に使用したものが一番上の実行サンプルです。
この方法なら事前にマップを用意しておくだけではなく、このように動的に埋めたり掘ったりしてもimage_indexの再割り当てが可能になります。

ちょっとしたミニゲームであればマップ作りがこれでかなり楽になりますので、試してみてください。