Повышение производительности обнаружения щелчков на изометрической сетке в шахматном порядке
Я работаю над изометрическим игровым движком и уже создал алгоритм для точного обнаружения кликов. Посетитьпроект и обратите внимание, что обнаружение щелчков способно определить, по какому краю плитки был нажат. Он также проверяет 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 (квадратная сетка приблизительно).
Если вы попали сюда, спасибо!