Во-первых, вот код. Объяснение будет следовать:
/*
* tw, th contain the tile width and height.
*
* hitTest contains a single channel taken from a tile-shaped hit-test
* image. Data was extracted with getImageData()
*/
worldToTilePos = function(x, y) {
var eventilex = Math.floor(x%tw);
var eventiley = Math.floor(y%th);
if (hitTest[eventilex + eventiley * tw] !== 255) {
/* On even tile */
return {
x: Math.floor((x + tw) / tw) - 1,
y: 2 * (Math.floor((y + th) / th) - 1)
};
} else {
/* On odd tile */
return {
x: Math.floor((x + tw / 2) / tw) - 1,
y: 2 * (Math.floor((y + th / 2) / th)) - 1
};
}
};
Обратите внимание, что этот код не будет работать из коробки для карты, показанной в вашем вопросе. Это потому, что у вас нечетные плитки смещены влево, тогда как нечетные плитки чаще смещены вправо (как в случае с редактором мозаичных карт ). Вы можете легко исправить это, настроив значение x, возвращаемое в случае нечетного тайла.
объяснение
Это может показаться чуть более грубым методом выполнения этой задачи, но он, по крайней мере, имеет преимущество в том, что он идеально подходит для пикселей и немного более гибок.
Хитрость заключается в просмотре карты не в виде одной ступенчатой сетки, а в виде двух сеток, наложенных друг на друга. Есть сетка с нечетными строками и сетка с четными строками, но давайте назовем их красными и зелеными, чтобы мы могли создать красивую диаграмму ...
Обратите внимание, что справа от этого изображения я пометил точку с фиолетовой точкой. Это пример, который мы постараемся найти в нашем оригинальном тайле-пространстве.
Что следует отметить в любой точке мира, так это то, что она всегда будет лежать ровно в двух областях - красной и зеленой (если только она не на краю, но в любом случае вы, вероятно, будете обрезать границу с неровными краями). Давайте найдем эти регионы ...
Теперь, чтобы выбрать, какой из двух регионов является правильным. Всегда будет ровно один ответ.
Отсюда мы могли бы сделать более простую арифметику и вычислить квадратное расстояние от нашей точки выборки до каждой центральной точки двух областей. Наш ответ будет самым близким.
Однако есть альтернативный способ. Для каждой тестовой области мы выбираем растровое изображение, которое соответствует точной форме наших плиток. Мы производим выборку в точке, переведенной в локальные координаты для этой отдельной плитки. Для нашего примера это будет выглядеть примерно так:
Слева мы проверяем зеленую область и получаем удар (черный пиксель). Справа мы тестируем красную область и получаем промах (белый пиксель). Второй тест, конечно, является излишним, поскольку он всегда будет точно тем или иным, а не обоими.
Затем мы приходим к выводу, что у нас есть хит в нечетном тайле на 1,1. Эта координата должна быть простой для сопоставления с исходными координатами плитки, используя другое преобразование для нечетных и четных строк.
Этот метод также позволяет вам иметь простые свойства для каждого пикселя в битовых картах теста пикселей. Например, белый не в цвете, черный - хит, синий - вода, красный - твердый.