From 7402d22c53167bd498d648434822c145d39b7817 Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Fri, 2 Oct 2020 10:57:57 +0100 Subject: [PATCH] `Tilemaps.Components.HexagonalWorldToTileXY` is a new function that converts world coordinates to hexagonal tile coordinates. --- .../components/HexagonalWorldToTileXY.js | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/tilemaps/components/HexagonalWorldToTileXY.js diff --git a/src/tilemaps/components/HexagonalWorldToTileXY.js b/src/tilemaps/components/HexagonalWorldToTileXY.js new file mode 100644 index 000000000..008224118 --- /dev/null +++ b/src/tilemaps/components/HexagonalWorldToTileXY.js @@ -0,0 +1,64 @@ +/** + * @author Richard Davey + * @copyright 2020 Photon Storm Ltd. + * @license {@link https://opensource.org/licenses/MIT|MIT License} + */ + +var Vector2 = require('../../math/Vector2'); + +/** + * Converts from world XY coordinates (pixels) to hexagonal tile XY coordinates (tile units), factoring in the + * layer's position, scale and scroll. This will return a new Vector2 object or update the given + * `point` object. + * + * @function Phaser.Tilemaps.Components.HexagonalWorldToTileXY + * @since 3.50.0 + * + * @param {number} worldX - The x coordinate to be converted, in pixels, not tiles. + * @param {number} worldY - The y coordinate to be converted, in pixels, not tiles. + * @param {boolean} [snapToFloor=true] - Whether or not to round the tile coordinates down to the nearest integer. + * @param {Phaser.Math.Vector2} [point] - A Vector2 to store the coordinates in. If not given a new Vector2 is created. + * @param {Phaser.Cameras.Scene2D.Camera} [camera=main camera] - The Camera to use when calculating the tile index from the world values. + * @param {Phaser.Tilemaps.LayerData} layer - The Tilemap Layer to act upon. + * + * @return {Phaser.Math.Vector2} The XY location in tile units. + */ +var HexagonalWorldToTileXY = function (worldX, worldY, snapToFloor, point, camera, layer) +{ + if (snapToFloor === undefined) { snapToFloor = true; } + if (point === undefined) { point = new Vector2(); } + + var tileWidth = layer.baseTileWidth; + var tileHeight = layer.baseTileHeight; + var tilemapLayer = layer.tilemapLayer; + + if (tilemapLayer) + { + if (camera === undefined) { camera = tilemapLayer.scene.cameras.main; } + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's vertical scroll + + worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY)); + + tileHeight *= tilemapLayer.scaleY; + + // Find the world position relative to the static or dynamic layer's top left origin, + // factoring in the camera's horizontal scroll + + worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX)); + + tileWidth *= tilemapLayer.scaleX; + } + + var len = layer.hexSideLength; + var rowHeight = ((tileHeight - len) / 2 + len); + + // similar to staggered, because Tiled uses the oddr representation. + var y = (snapToFloor) ? Math.floor((worldY / rowHeight)) : (worldY / rowHeight); + var x = (snapToFloor) ? Math.floor((worldX - (y % 2) * 0.5 * tileWidth) / tileWidth) : (worldX - (y % 2) * 0.5 * tileWidth) / tileWidth; + + return point.set(x, y); +}; + +module.exports = HexagonalWorldToTileXY;