Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MapSpriteで各レイヤー毎にTileset画像を指定できるようにしたい #122

Open
emadurandal opened this issue Jul 6, 2014 · 10 comments

Comments

@emadurandal
Copy link
Contributor

こんにちはー。

表題の通りの要望ですー。
以下の様な感じにできると素敵だなーと思いまして。

  MAP_DATA = {
    'map.001': {
      name: '001',
      width: 10,
      height: 10,
      tilewidth: 64,
      tileheight: 64,
      tilesets: [
        {
          name: 'layer1',
          image: 'hoge.jpg'
        },
        {
          name: 'layer2',
          image: 'hoge2.jpg'
        }
      ],
      layers: [
        {
          type: 'layer',
          name: 'layer1',
          data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 
                 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        },
        {
          type: 'layer',
          name: 'layer2',
          data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 
                 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 
                 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        }
      ]
    }
  };

tmlibのコードのtm.display.MapSpriteの定義内のコードを以下のような感じにしたら(すっごい初心者なコード(汗))、とりあえず行けたのですが、

        _buildLayer: function(layer) {
            var self        = this;
            var mapSheet    = this.mapSheet;
            var tilesetUrl = "";
            for(var i = 0; i<mapSheet.tilesets.length; i++) {
                if(mapSheet.tilesets[i].name === layer.name) {
                    tilesetUrl = mapSheet.tilesets[i].image;
                    break;
                }
            }
            var texture     = tm.asset.Manager.get(tilesetUrl);
            .....

他のコード部分との整合性とか大丈夫か自信がなかったのでプルリクでなくイシューで上げさせていただきました。

ご検討よろしくお願いいたします。

@fukuyama
Copy link
Contributor

fukuyama commented Jul 7, 2014

Tiled map XML (tmx) 的には、複数の tileset を指定した場合は、全部をマージした tileset 1つになるみたいですね。

tmx はとりあえず置いておいて、
レイヤー1つにタイルセット1つって対応付けるなら…レイヤー側に、使うタイルセットを設定したほうがしっくりくる気がします。1つのタイルセットは、複数のレイヤーで使うかな~と。

tilesets: [
  {
    name: 'layer1',
    image: 'hoge.jpg'
  },
  {
    name: 'layer2',
    image: 'hoge2.jpg'
  }
],
layers: [
  {
    type: 'layer',
    name: 'layer1',
    tileset: 0 もしくは 'layer1',
    data: [...]
  }
]

1つのレイヤーで複数のタイルセットも使いたくなるから、Tiled では、全部1つにしてる気がしますね…

@emadurandal
Copy link
Contributor Author

@fukuyama あ、たしかにレイヤー側に設定できた方が良いですね。

Tiled map XMLは私よく知らないんですが、全部一つのタイルセットにすると、
dataの、タイルのインデックスの指定が少しややこしくなるのがネックかなーと。

Tiledの場合と、この場合、両方認めてくれるとうれしーです♪

@fukuyama
Copy link
Contributor

fukuyama commented Jul 9, 2014

たぶん、福山もそのうち使いたくなるので、ちょっと手をつけてみようかな~

MapSprite は、1つのレイヤーで複数のタイルセットとか、複数のレイヤーに、1つのタイルセットとか
多対多にできると何でもできるとおもうので tmx よりの、全部1つにしてなんでも使える状態が
いい気がします。

MapSheet か、その派生クラスの初期化方法の1つとして、
レイヤーが使うタイルセットを指定する方法とか data に、そのタイルセットの番号しか書かないって初期化方法を用意する。(内部的には、全タイルセットの通し番号に変換とか)

で、tmx での初期化とか、json での初期化とか、その他でも対応出来る感じがする。
data を通し番号に変換するヘルパー関数ってだけでもいいかも?

@phi-jp
Copy link
Owner

phi-jp commented Jul 10, 2014

watch

@fukuyama
Copy link
Contributor

自分のforkしたほうでは、できました~。
結局、MapSprite でがんばるようにしてみました。MapSheetだと、asset だからいろいろ後で大変かな~と思って、とりあえず。

#125 がマージされたら、それをさらに修正って感じでプルリクします。
よろしくお願いします。 @phi-jp さま
なにか問題あったら、修正します。

    # タイルセット
    tilesets: [
      {
        name: 'pink'
        image: 'img/test03.png'
      }
      {
        name: 'blue'
        image: 'img/test04.png'
      }
    ]

    # マップレイヤー
    layers: [
      {
        type: 'layer'
        name: 'layer1'

        tilesets: ['blue','pink']

        data: [
          5, 0, 0, 0, 5
          0, 0, 0, 0, 0
          0, 0,-1, 0, 0
          0, 0, 0, 0, 0
          0, 0, 0, 0, 0
        ]
      }
    ]

こんな感じです。今のところ。

layer の方の tilesets には、数値、文字列、数値配列、文字列配列が指定できて、
数値は、タイルセットのインデックス。文字列は、タイルセット名。
配列の場合は、その順番でマージされたタイルセットとして layer.data を MapSprite でつかう。

layer の tilesets 指定が無い場合は、もともとのタイルセットの順番。(tmxの場合は無い)

@emadurandal
Copy link
Contributor Author

@fukuyama わー、ステキです!
私もプルリクできるように、tmlib.jsの仕様をちゃんと理解しないとなー^^;

この例の場合は、pink(test03.png)とblue(test04.png)の画像がマージされて、layer.data配列内の各セルの数値は、そのマージされた画像のセルのインデックスを指すという理解でよいでしょうか?

@fukuyama
Copy link
Contributor

@emadurandal
上の例の場合は、blue(test04.png) + pink(test03.png) の順でマージですね。
layer.tilesets では、マージする順番を、指定する感じです。

tilesets: 'blue' だと、test04.png だけ使う感じです。tilesets: 1 でも同じ。
tilesets: ['pink','blue'] だと、設定しない場合と一緒。
(tmxと同じ。pink + blue の順番でマージしたインデックス)

@emadurandal
Copy link
Contributor Author

developに取り込まれたようなので、早速使ってみたのですが、
上の例でいうと、
2つ目のレイヤーを追加したとして、そのレイヤーでtilesets: 'blue' を指定したのですが、

2つ目のレイヤーのdataの配列で要素に0を指定すると、blue(test04.png)の最初のマップチップでなく、pink(test03.png)の最初のマップチップが表示されてしまいます。なので、現状pink(test03.png)のタイル数を覚えておいて、その数だけオフセットしないといけない(pink(test03.png)のタイル数が5だったら、レイヤー2のdataでblue(test04.png)の最初のマップチップを表示したいときは5、2番目のマップチップを表示したいなら6を指定しないといけない)状況です。

これ、オフセットを内部で自動でやってくれるようにはできないでしょうか?

@fukuyama
Copy link
Contributor

@emadurandal
もう少々お待ちを~
今のマージは、tmx に対応しただけなので、さらにプルリクします。

@emadurandal
Copy link
Contributor Author

ありがとうございます。なんだか要求してばっかりですみません(汗)
私も最近tmlib.jsのコードリーディング始めましたので、
そのうちちゃんとプルリクして貢献できるようになるかと^^;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants