Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   курсор над объектом MovieClip (http://www.flasher.ru/forum/showthread.php?t=134123)

k0syak 22.12.2009 12:40

курсор над объектом MovieClip
 
Доброе время суток. в целом задача следующая: есть MovieClip, который может быть как растровым так и векторным. и необходимо узнать находится ли курсор на объекте. т.е. если это картинка, то необходимо выдавать true (что означает что курсор над объектом) тогда когда курсор действительно попал на объект, а не на пустую область в прямоугольнике. Что можете посоветовать?

Jewelz 22.12.2009 12:58

вы имеете ввиду что картинка с прозрачностью? тогда проверяйте на пиксель с альфой 0

dimarik 22.12.2009 13:05

Если это растр, то он всегда прямоугольник и курсор действительно всегда попадает на объект. Пустая область - это пиксели растра с альфа=0. Анализируйте прозрачность пикселя под курсором.

Добавлено через 32 секунды
Аха, опередили =)

k0syak 23.12.2009 18:24

дело в том что я не знаю картинка это или мувик. И то что там лежит может сменится в любой момент.

silin 23.12.2009 18:58

>>не знаю картинка это или мувик
остается срисовывать содержимое в битмап (BitmapData#draw) и опять же смотреть прозрачность пикселя под курсором

iflamberg 23.12.2009 18:58

ну так устанавливайте для мувика какой-нибудь флаг, чтобы знать мувик там или битмапа. Или используйте проверку типа if (mc is MovieClip) ... .

mayakwd 23.12.2009 19:02

Цитата:

Сообщение от k0syak (Сообщение 874632)
дело в том что я не знаю картинка это или мувик. И то что там лежит может сменится в любой момент.

о боже, но оно же грузится у вас верно? на момент загрузки ставите слушателя, проверяете мувиклип это или битмапа, ставите флаг и далее по алгоритму при наведении делаете то или иное действие.

dimarik 24.12.2009 01:05

Цитата:

Сообщение от k0syak (Сообщение 874632)
И то что там лежит может сменится в любой момент.

Это немного усложняет дело. Вам нужно на хэндлере MOUSE_MOVE делать проверку event.target на принадлежность классу Bitmap. Если последнее имеет место, то производите проверку Bitmap(event.target).bitmapData на пиксели с альфа=0 под курсором. Сложнее будет, если есть необходимость игнорировать прозрачные писксели внутри границ.

MerlinTwi 24.12.2009 14:23

Вложений: 1
Ситуация сложнее. Если внутри мувиклипа лежит безымянная картинка, то flash IDE из нее делает Shape, а не Bitmap!
И при проверке пересекающихся мувиклипов надо еще определять, кто выше находится.

Столкнувшись с аналогичной ситуацией я написал такой класс, может и вас пригодится:
Код AS3:

package { // CheckMouseOver.as
        import flash.display.BitmapData;
        import flash.display.DisplayObject;
        import flash.geom.Matrix;
        import flash.geom.Point;
        import flash.geom.Rectangle;
 
        /** Для определения находится ли мышка над непрозрачной областью мувиклипа */
        public class CheckMouseOver {
 
                /** до какого размера уменьшать картинки */
                private const BITMAP_SIZE:int = 64;
 
                /** Какой мувиклип проверяем */
                public var mc:DisplayObject;
                /** На каком слое у родителя лежит этот mc */
                public var parentIndex:int;
                /** прямоугольник описывающий мувиклип */
                public var bounds:Rectangle;
 
                private var bd:BitmapData;
                private var dx:Number, dy:Number;
                private var p:Point = new Point();
 
                public function CheckMouseOver(mc:DisplayObject) {
                        if (mc && mc.width > 0) {
                                this.mc = mc;
                                if (mc.parent) parentIndex = mc.parent.getChildIndex(mc);
                                bounds = mc.getBounds(null);
                                // для экономии памяти и сглаживания мелких дырок на картинке
                                // сохраняем картинку уменьшенную до BITMAP_SIZE
                                dx = BITMAP_SIZE / bounds.width;
                                if (dx > 1) dx = 1;
                                dy = BITMAP_SIZE / bounds.height;
                                if (dy > 1) dy = 1;
                                bd = new BitmapData(bounds.width * dx, bounds.height * dy, true, 0);
                                bd.draw(mc, new Matrix(dx, 0, 0, dy, -bounds.x * dx, -bounds.y * dy));
                        } else {
                                trace("Empty MovieClip!", mc);
                        }
                }
 
                /** Проверяет, попадает ли указанная точка сцены в наш мувиклип */
                public function check(stageX:Number, stageY:Number):Boolean {
                        if (mc) {
                                p.x = stageX;
                                p.y = stageY;
                                var p2:Point = mc.globalToLocal(p);
                                if (bounds.containsPoint(p2)) { // мышка попала в наш прямоугольник, проверяем пиксель на прозрачность
                                        var color:uint = bd.getPixel32((p2.x - bounds.x) * dx, (p2.y - bounds.y) * dy);
                                        if (((color >> 24) & 0xFF) > 128) return true;
                                }
                        }
                        return false;
                }
 
                /** Очистить память */
                public function dispose():void {
                        if (bd) bd.dispose();
                        bd = null;
                        mc = null;
                        bounds = null;
                        p = null;
                }
        }
}

пример использования: допустим, у нас на сцене размещены 5 мувиклипов с именами "b0..b4" и нужно их подсвечивать при наведении мышки

Код AS3:

package {
        import flash.display.MovieClip;
        import CheckMouseOver;
        import flash.events.MouseEvent;
        import flash.filters.GlowFilter;
 
        dynamic public class Test extends MovieClip {
 
                /** Сюда складываем CheckMouseOver, которые будем проверять при движении мышки */
                var allObjects:Array;
                /** над каким мувиклипом мышка была в последний раз */
                var lastMouseOver:CheckMouseOver;
                /** Фильтр для подсветки мувиклипа */
                const lightFilter:Array = [new GlowFilter(0xFFFFFF, 1, 16, 16)];
 
                public function Test() {
                        allObjects = new Array();
                        for (var i:int = 0; i < 5; i++) {
                                allObjects.push( new CheckMouseOver(this["b" + i]) );
                        }
                        // сортируем allObjects по слоям
                        allObjects.sortOn('parentIndex', [Array.NUMERIC | Array.DESCENDING]);
                        // слушаем движения мышки
                        stage.addEventListener(MouseEvent.MOUSE_MOVE, onMMove);
                }
 
                private function onMMove(e:MouseEvent):void {
                        // пытаемся определить, над каким объектом находится мышка
                        var x0:int = stage.mouseX, y0:int = stage.mouseY;
                        var atc:CheckMouseOver;
                        for each (var c:CheckMouseOver in allObjects) {
                                if (c.check(x0, y0)) {
                                        atc = c;
                                        break;
                                }
                        }
                        if (lastMouseOver === atc) return; // ничего не изменилось
                        if (lastMouseOver) {
                                // выключаем подсветку у предыдущего объекта
                                lastMouseOver.mc.filters = null;
                        }
                        lastMouseOver = atc;
                        if (lastMouseOver) {
                                // включаем подсветку
                                lastMouseOver.mc.filters = lightFilter;
                        }
                }
        }
}

в аттаче живой пример

k0syak 26.12.2009 18:18

Спасибаа!! Это все здорово работает. Только вот проблема. У меня мувик расположен не полностью на своём stage, а выше его (это необходимо для последующей привязки) и та часть которая на stage выделяется отлично, а та что выше не реагирует. Что можете посоветовать???

Добавлено через 69 часов 8 минут
Все, всем спасибо!! Все заработало. Убрал сторки, где меняется размер изображения


Часовой пояс GMT +4, время: 23:55.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.