TiledMap のタッチイベントに悩まされた

ゲーム制作

前回、TiledMap で、Isometric Map を作って、Cocos Creator で表示をしました。

で、今回は、タッチした箇所のマップタイルに変化を与えようと思って、作っていたんだけどすごい大変だった。

とりあえず、結果はこんな感じになります。

タッチしたところが、虫食いになります。

スクリーン座標とマップ座標の変換が大変だった。

Cocos2d-js に スクリーン座標と Isometric マップ座標を変換してくれる関数があるもんだと思っていたら無いんですね。

そんなこんなで、大雑把ですが変換できたので紹介します。

TiledMap の Anchor は左下で

まず悩まされたことで、TiledMap の Anchor は左下(0, 0)にしないと、正しく変換できませんでした。

Anchor を 0,0 にすることで、矢印が付いた青四角が左下に行きます。

タッチされたスクリーン座標はアンカーを基準に計算されるため、これをしないとマップとのズレが発生します。

TiledMap にタッチイベントを書く

タッチイベント

恒例で、onLoad イベントにゴリゴリ処理を書いていきます。

onLoad() {
  var self = this;
  self.node.on(cc.Node.EventType.TOUCH_START, function (event) {
    var touches = event.getTouches();
    var vec2 = tiledLayerNode.convertTouchToNodeSpace(touches[0]);
    var pos = screen_to_map(tiledLayer, vec2);
    var tile = tiledLayer.getTiledTileAt(pos.x, pos.y, true);
    var tileNode = tile.node;
    tileNode.runAction(cc.blink(1, 5));
  }, self.node);
}

5行目: タッチされたスクリーン座標を、マップレイヤー基準の座標に変換しています。
6行目: screen_to_mapでスクリーン座標からマップ座標に変換しています。
7~9行目: 取れたマップ座標を元に、タイルを取得してアクションを設定しています。

スクリーン座標からマップ座標に変換する処理

var screen_to_map = function(mapLayer, pos) {
    var wx = pos.x - (self.node.width / 2);
    var wy = pos.y - (self.node.height);
    var tw = mapLayer.getMapTileSize().width;
    var th = mapLayer.getMapTileSize().height;
    var twh = tw / 2;
    var thh = th / 2;
    var x = Math.abs(Math.floor((wy / thh - (wx / twh)) / 2));
    var y = Math.abs(Math.floor((wx / twh + wy / thh) / 2));
    cc.log("pos: " + x + ", " + y);
    return { x, y }
}

私も100%理解して使っているわけじゃないので、あまり詳しく説明できないのです。

とりあえず、この書き方で思った動きが出来たので載せておきます。

こちらのサイトから、Isometric 変換の考え方やソースを参考にさせて頂きました。

Isometric Tiles Math

おわりに

これといって大したことしてませんが、記事にしないと忘れちゃうので備忘録な感じです。

タイトルとURLをコピーしました