Эффективная нерегулярная область попадания растрового изображения - PullRequest
2 голосов
/ 08 сентября 2011

У меня есть проект Flash, который должен отображать большое количество растровых изображений неправильной формы (около 10000), и я хочу знать, над каким растровым изображением на данный момент находится мышь.Если мышь находится над прозрачной частью растрового изображения, она не должна учитываться как указатель мыши.

Один из способов сделать это - вычислить область попадания, а затем заменить каждое растровое изображение на Sprite, содержащеерастровое изображение и еще один Sprite с вычисленной областью попадания, затем установите свойство hitArea.Но это крайне неэффективно, а результат совершенно непригоден.

Какой самый эффективный способ сделать это?

Ответы [ 6 ]

6 голосов
/ 14 сентября 2011

Попробуйте это на контейнере:

var hits:Array = getObjectsUnderPoint(new Point(mouseX, mouseY));
if(hits.length > 0)
{
    var bitmap:Bitmap = hits[0] as Bitmap;
    var color:uint = bitmap.bitmapData.getPixel32(bitmap.mouseX, bitmap.mouseY);
    if(color >>> 24 > 0)
    {
        trace('hit: '+bitmap);
    }
}

Если растровые изображения перекрываются, выполните итерацию по hits. Вы также можете установить порог прозрачности.

2 голосов
/ 08 сентября 2011

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

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

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

2 голосов
/ 08 сентября 2011

Проверьте этот прозрачный пример PNG из , я думаю, что это может быть именно то, что вы ищете.

Вот ссылка на демо.1007 *

Удачи.

1 голос
/ 14 сентября 2011

У меня нет кода для этого на макушке, но вы могли бы создать слой для каждого растрового изображения, в котором вы залили изображение плоским цветом, с другим цветом для каждого изображения,Затем по щелчку мыши сделайте скриншот плоских цветовых слоев и проверьте цвет пикселя под мышью.

ДОПОЛНЕНИЕ: Только что увидел ваш комментарий, что растровые изображения не перемещаются.Это означает, что вам не нужно делать снимок экрана по щелчку мыши;просто сделайте снимок экрана один раз при первой загрузке растровых изображений.

0 голосов
/ 14 сентября 2011

Большая проблема заключается в огромном количестве изображений, которые можно зациклить и проверить на прозрачность.Если растровые изображения и их расположение не сильно изменяются (относительно друг друга), то есть довольно чистое решение:

Make an array of bitmaps(references to bitmaps actually so not consuming a 
gigamount of memory) the size of your screen (or even bigger when you want
to be able to pan around in a bigger area like in a platform game for example).

Loop over all images in z order (beginning with the image furthest away)
  [Calculate a mask for each image (making a black and white bitmap, white is transparent, black is everything else)]
  Loop over the pixels in the image [mask] and update the array (mind the offset) to the current bitmap if not transparent

Теперь каждый раз, когда вы хотите получить изображение, на котором мышь находится, вы можетеиспользуйте этот массив, чтобы найти его.

Вам придется пересчитывать его каждый раз, когда меняется макет.

Это дает вам общие рекомендации, возможны многие варианты оптимизации.

0 голосов
/ 11 сентября 2011

Если растровые изображения являются экранными объектами, используйте метод DisplayObjectContainer: getObjectsUnderPoint (). Это обрабатывает неправильные векторные объекты правильно, но я не пробовал с растровыми объектами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...