Я создал изометрическую среду на Javascript и HTML5 (2D Canvas), которая в основном работает нормально. Проблема, с которой я столкнулся, связана с наличием плиток разной высоты и последующей сортировкой индексов объектов на плитках (в данном случае при перемещении между двумя плитками бок о бок).
Например, один объект может находиться за плиткой перед ним, потому что высота плитки, на которой он находится, равна -1. Решение, которое я придумал, заключалось в том, чтобы рисовать каждый объект плитки сразу после рисования плитки, начиная с 0,0 и оттягивая оттуда каждую строку и столбец.
Это хорошо работает до тех пор, пока мне не понадобится переместить объект между двумя плитками. На этом этапе либо объект должен использовать промежуточную плитку (это реализовано на изображениях ниже), либо плитка будет перекрывать объект, поскольку плитка рисуется после объекта. Использование промежуточного тайла также создает проблему, когда объект ограждения в той же «строке» перерисовывается, потому что куб использует гораздо более высокий z-index из тайла 1,3 (это немного видно на изображении 1).
http://i.stack.imgur.com/PQJ0H.png
http://i.stack.imgur.com/DupM7.png
Я думаю, что испытанный и проверенный способ рисования изометрической среды - это просто иметь 1 слой для плиток и 1 слой для объектов, и тогда объекты никогда не могут находиться за плитками, но это просто ограничение, которого я не хочу придерживаться.
Итак, мой вопрос: при рисовании всей среды сверху вниз (или любым другим способом, если это позволяет), рисовании каждой плитки и ее объектов по очереди, есть ли умный способ отложить рисование объекта или создать массив объектов, которые нужно рисовать в правильном порядке? Кто-нибудь еще сталкивался с подобными проблемами и нашел ли кто-нибудь решения для этого?
Вся помощь очень ценится.
Пример моего тайлового кода:
// each column
for(y=0; y<totalColumns; y++){
// each row
for(x=0; x<totalRows; x++){
tile = tiles[y][x];
// draw tile
drawTile(tile);
objects = objects[y][x];
// draw objects for that tile
drawObjects(objects);
}
}
Редактировать:
Одно из решений, которое я придумал (после прочтения вопроса самому себе), - это перебрать все плитки, получить массив высот плиток, отсортировать их, а затем выполнить традиционный рисунок. Вот так:
var layers = [];
for(var y=0; y<cols; y++){
for(var x=0; x<rows; x++){
tile = tiles[y][x];
if(!layers.indexOf(tile.height)) layers.push(tile.height);
}
}
// sort layers
layers.sort(/*function here to sort layers*/);
for(l=0; l<layers.length; l++){
// draw tiles for this layer
// draw objects for this layer
}
Возможны ли другие решения?