|
|
|||||
Регистрация: Nov 2012
Сообщений: 4
|
Прозрачность спрайтов и hover
Доброго времени суток.
Сразу хочу сказать, что я не профи и только начинаю познавать дао action script. =) Собственно возникла такая проблема. У меня есть кусочки карты нашей планеты (в пнг), и по ховеру на них нужно делать некие действия. Но, предположим, есть вся европа и греция отдельно. Собственно кусочки карты наношу примерно таким кодом: this.sprite.graphics.beginBitmapFill(this.imageBitmap, null, false); this.sprite.graphics.drawRect(0, 0, this.imageBitmap.width, this.imageBitmap.height); this.sprite.graphics.endFill(); теперь суть проблемы. греция имеет несколько не квадратную форму, поэтому при наведении на прозрачный пиксель спрайта должно отрабатывать событе hover на подложку (то есть всю европу). спрайты по наведению надо скрывать \ отображать, поэтому bubbling не совсем подходит... В принципе я решил проблему так: * слушаю перемещение мыши по всей сцене * относительно положения курсора мыши проверяю какие из спрайтов "в фокусе" и с ними уже работаю. то, что-то мне подсказывает, я изобрел новый геморрой, поэтому прошу подсказки у сообщества =) |
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Не знаю, что заставило Вас использовать Битмап для заливки векторной формы, но лучше отказаться от этого, так как выигрыша при рисовании прямоугольной формы Вы не получаете (то есть, если бы форма региона была отрисована кривыми и совпадала с формой [страны], мышь ловилась бы только на залитой области. Если залит весь прямоугольник, то он весь и ловит мышь). Если возможности отрисовать страны в точные формы нет, Вам придется использовать что-то типа InteractivePNG, то есть создавать не просто спрайты, а наследников специального класса, умеющего различать, находится мышь над прозрачной областью его содержимого или нет.
InteractivePNG универсален, и оттого сильно перегружен. Если нужно решать только судьбу клика или нажатия на объект, можно написать класс намного проще. package { import flash.events.Event; import flash.display.Bitmap; import flash.display.Sprite; import flash.events.MouseEvent; import flash.geom.Point; import flash.geom.Rectangle; /* * * * * * * * * * * * * @author wolsh * * * \* * * * * * * * * */ public class InteractiveImage extends Sprite { private var _bounds:Rectangle; private var _image:BitmapData; public function InteractiveImage(image:BitmapData) { _image = image; this.addChild(new Bitmap(_image)); this.mouseChildren = false; _bounds = this.getBounds(this); if (stage) init(); else this.addEventListener(Event.ADDED_TO_STAGE, init); } private function init(event:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point this.addEventListener(Event.REMOVED, removedHandler); this.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler, false, 10000, true); } /* HANDLERS */ private function removedHandler(e:Event):void { stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); } //// Когда мышь попадает в границы клипа, private function rollOverHandler(event:MouseEvent):void { this.removeEventListener(MouseEvent.ROLL_OVER, rollOverHandler, false); //// отключаем ему реакцию на мышь, чтобы события мыши достигали нижележащих клипов. this.mouseEnabled = false; //// Однако слушаем движение мыши через стейдж. stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); } //// после того, как мышь попала в границы клипа, на каждое движение мыши private function mouseMoveHandler(event:MouseEvent):void { //// проверяем, находится ли еще мышь в границах клипа. var mousePoint:Point = new Point(this.mouseX, this.mouseY); //// Когда мышь покидает границы клипа (клип уже не мешает событиям мыши достигать нижних клипов), if (!_bounds.containsPoint(mousePoint)) { //// снова включаем реакцию, this.mouseEnabled = true; //// чтобы поймать ролловер в следующий раз. this.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler, false, 10000, true); //// и перестаем слушать движение мыши по стейджу stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); } else //// если мышь все еще в границах клипа... { //// Когда мышь попадает на непрозрачные пиксели клипа, снова включаем реакцию на мышь; когда на прозрачные — снова отключаем. this.mouseEnabled = _image.hitTest(new Point(), 0x22, mousePoint); } } } }
__________________
Reality.getBounds(this); |
|
|||||
Регистрация: Nov 2012
Сообщений: 4
|
Цитата:
ИнтерактивПнг помог, спасибо. Поковыряюсь в его коде, может зацеплюсь за умные мысли. В процессе гугления про интерактивпнг наткнулся на топик в котором обсуждалось, что можно ограничить зону реакции мыши в спрайте через hitArea и маску. Сорри за нубский вопрос, но можно ли создать программно некий полигон и использовать его в качестве маски для этих целей? |
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Повторю то, что написано в начале моего сообщения — если у Вас есть возможность создать векторную форму региона (не прямоугольную, а именно по границам региона), то ее можно просто залить битмапдатой, как Вы и делали. Никакая маска тогда не нужна — пустоты итак не будут реагировать на мышь.
__________________
Reality.getBounds(this); |
Часовой пояс GMT +4, время: 02:08. |
|
« Предыдущая тема | Следующая тема » |
|
|