Повышение производительности обнаружения щелчков на изометрической сетке в шахматном порядке

Я работаю над изометрическим игровым движком и уже создал алгоритм для точного обнаружения кликов. Посетитьпроект и обратите внимание, что обнаружение щелчков способно определить, по какому краю плитки был нажат. Он также проверяет y-индекс, чтобы щелкнуть по самой открытой плитке.

Объяснение моего текущего алгоритма:

Изометрическая сетка состоит из мозаичных изображений размером 100 * 65 пикселей.TileW=100, TileL=50, tileH=15

Карта представлена ​​трехмерным массивомmap[z][y][x].

Центральные точки плитки(x,y) рассчитываются так:

//x, y, z are the position of the tile

if(y%2===0) { x-=-0.5; }    //To accommodate the offset found in even rows
this.centerX = (x*tileW) + (tileW/2);
this.centerY = (y*tileL) - y*((tileL)/2) + ((tileL)/2) + (tileH/2) - (z*tileH);

Функции прототипа, которые определяют, находится ли мышь в заданной области на плитке:

Tile.prototype.allContainsMouse = function() {
    var dx = Math.abs(mouse.mapX-this.centerX),
        dy = Math.abs(mouse.mapY-this.centerY);

    if(dx>(tileW/2)) {return false;}    //Refer to image
    return (dx/(tileW*0.5) + (dy/(tileL*0.5)) < (1+tileHLRatio));
}

Tile.prototype.allContainsMouse() возвращает true, если мышь внутри зеленого цвета. Красная область обрезается, проверяя, dx> половина ширины плитки

Tile.prototype.topContainsMouse = function() {
    var topFaceCenterY = this.centerY - (tileH/2);
    var dx = Math.abs(mouse.mapX-this.centerX),
        dy = Math.abs(mouse.mapY-topFaceCenterY);

    return ((dx/(tileW*0.5) + dy/(tileL*0.5) <= 1));
};

Tile.prototype.leftContainsMouse = function() {
    var dx = mouse.mapX-this.centerX;
    if(dx<0) { return true; } else { return false; }
};

(Если мышь находится слева от центральной точки)

Tile.prototype.rightContainsMouse = function() {
    var dx = mouse.mapX-this.centerX;
    if(dx>0) { return true; } else { return false; }
};

(Если мышь находится справа от центральной точки)

Объединение всех методов в единую систему:

Цикл по всему массиву 3d map [z] [y] [x]еслиallContainsMouse() возвращает true, map [z] [y] [x] - это плитка, на которой находится наша мышь.Добавить эту плитку в массивtilesUnderneathMouse массив.

ПереберитеtilesUnderneathMouse массив, и выберите плитку с самым высокимy, Это самая прямая плитка.

if(allContainsMouse && !topContainsMouse)

if(allContainsMouse && !topContainsMouse && leftContainsMouse)

(Аналогичная концепция применяется для права)

Напоследок мои вопросы:

# 1 Как бы вы достигли этого, чтобы он был более эффективным (без циклического прохождения всех фрагментов) (принят псевдокод)

# 2 Если вы не можете ответить # 1, какие предложения у вас есть, чтобы повысить эффективность обнаружения моих кликов (загрузка чанка уже была рассмотрена)

Что я подумала о:

Первоначально я пытался решить эту проблему, не используя центральные точки плитки, а преобразовав положение мыши (x, y) непосредственно в плитку x, y. На мой взгляд, это самое трудное для кода, но самое эффективное решение. На квадратной сетке очень легко преобразовать (x, y) позицию в квадрат на сетке. Однако в шахматной сетке столбцов вы имеете дело со смещениями. Я попытался вычислить смещения, используя функцию, которая принимает значение x или y и возвращает результирующее смещение y или x. Зигзагообразный графикагссоз (cosx) решил это.

Проверить, была ли мышь внутри плитки, использовать этот метод было сложно, и я не мог понять это. Я проверял, была ли мышь (x, y) подy=mx+b линия, которая зависела от плиткиX, аппроксимация плиткиY (квадратная сетка приблизительно).

Если вы попали сюда, спасибо!

Ответы на вопрос(1)

Ваш ответ на вопрос