PDA

Просмотр полной версии : hitTestPoint без цикла проверки детей


dvrbear
06.03.2012, 16:20
на сцене к примеру есть мувик "pole"
в нем дофига других мувиков (мелких кружков)

проверка поставленна только на pole
if(pole.hitTestPoint(mouseX, mouseY, true))

возможно ли отловить на кого именно из детей попадает мышь?
(чтоб к примеру удалить конкретный мувик из pole)

* без включения цикла - не проходясь проверкой по кадому чайлду
** и не включая проверку в сами чайлды

in4core
06.03.2012, 17:12
MouseEvent.MOUSE_OVER # e.target

dvrbear
06.03.2012, 17:27
а если объект не MOUSE?
к примеру у меня 10 других объектов
10 "стрел" на сцене
1 000 000 "яблок" внутри "pole"

опятьже интересует проверка столкновения "стрела" и "pole"
и уж потом только узнать с которым из "яблок" именно столкнулся

но так чтоб не проверять в цикле каждое "яблоко"

п.с. спасибо за быстрый ответ на счет мыши - тоже пригодится

in4core
06.03.2012, 17:33
а если объект не MOUSE? Вы о чем вообще? Вешайте событие на поле и ловите таргет, при наведении мышкой и будет ваш внутренний клип.

dvrbear
06.03.2012, 17:40
ну не мышь будет участвовать в событие!

нет четкого задания я просто для себя пытаюсь понять - можно или нет

к примеру летает куча стрел и сшибает яблоки внутри "pole"
мышка вообще не причём

нужно узнать при хиттесте "pole" какого именно яблока каснулась стрела
если не возможно то я так понимаю придется включать цикл
на повторную проверку каждого из яблок

ну или же в яблоки писать проверку на столкновение со стрелами

просто хотел узнать можно ли обойтись без этих заморочек?

Wolsh
06.03.2012, 17:44
DisplayObjectContainer#getObjectsUnderPoint()

dvrbear
06.03.2012, 18:59
спасибо! то что надо!

правдо долгое время не мог исправит все баги
ведь метод выдавал самый нижний объект
и вместо MovieClip падал до самого низа до векторного Shape Object

а для таких как "Я" попытаюсь объяснить решение:

var pt:Point = new Point(mouseX,mouseY);
// точку можно заменить любыми координатами

var objects:Array = pole.getObjectsUnderPoint(pt);
// заносятся в массив все конечные объекты попадающие под точку
// в моем случае на сцене друг под другом
// pole.a1 и pole.a2 - в массив записались входящие в а1 и а2 [Shape Object]
// чтобы добраться до a1 - objects[0].parent

pole.removeChild(DisplayObject(objects[0].parent));
// удаляется конкретный мувик внутри pole

БЛАГОДАРЮ in4core и Wolsh

TanaTiX
06.03.2012, 19:20
А если objects[0].parent окажется другим шейпом или спрайтом?

dvrbear
06.03.2012, 19:38
ну поделитесь как тогда поступить?
я подозреваю, что должна быть реализована проверка на тип объекта

если знаете как опишите пожалуйста данную проверку
ну и на всякий случай метод удаления со сцены объектов не являющихся MovieClip-ами

Wolsh
06.03.2012, 20:42
Ну как-то так (с коленки):
var p:DisplayObject;
for (var i:uint = 0; i < objects.length; i++)
{
p = objects[i];
while(p != null)
{
if(p is Apple)
{
this.removeChild(p);
break;
}
p = p.parent;
}
}

TanaTiX
06.03.2012, 22:47
Wolsh, я бы сюда еще добавил проверку на общий для яблок контейнер и по его достижении сбрасывал бы цикл. Хотя целесообразность зависит от его (контейнера) глубины относительно stage.
var p:DisplayObject;
var cont:DisplayObjectContainer;
var length:int = objects.length;
for (var i:uint = 0; i < length; i++)
{
p = objects[i];
while(p != null)
{
if(p == cont)
{
break;
}
if(p is Apple)
{
this.removeChild(p);
break;
}
p = p.parent;
}
}

dvrbear
06.03.2012, 22:54
а что, созданный в ручную на сцене мувик в который вложены (програмно или вручную) другие мувики - автоматически приобретает тип DisplayObjectContainer ?

TanaTiX
06.03.2012, 22:59
MovieClip происходит от DisplayObjectContainer, поэтому все условия сохраняются, при этом мы не пользуемся не нужным функционалом спрайтов/мувиклипов.

dvrbear
06.03.2012, 23:07
почемуто на оба сравнения выдает false :(

//var cont:DisplayObjectContainer;
//var cont:MovieClip;
trace(pole == cont);

MikroAcse
06.03.2012, 23:15
trace(pole is DisplayObjectContainer, pole is MovieClip);

dvrbear
06.03.2012, 23:26
ага пасиб
тоже какраз такой ответ нашел

а то както страно было объявлять
переменную чтоб потом с ней сравнивать
да и parent - полюбому должен являться DisplayObjectContainer

кстатии объявить без ошибок получилось только так
странно почему DisplayObjectContainer не хочет прописываться по принципу MovieClip

//public var cont:DisplayObjectContainer;
//public var cont:MovieClip = new MovieClip();

TanaTiX
06.03.2012, 23:29
Тут поможет приведение типов.
В данном коде cont - он уже существует, я его написал, что бы показать что он есть и кто таков. Присвойте данной переменной ваш контейнер, где все яблоки находятся.

Wolsh
07.03.2012, 00:08
Вопрос скорее, у какого контейнера вызывается метод getObjectsUnderPoint() :)
Что-то мне подсказывает, что сам контейнер не может оказаться в списке своих детей под точкой.
Так что я бы вызывал этот метод у нужного контейнера, а не у рута и не у стейджа, и не включал эту избыточную проверку. Но тогда точку надо переводить в локаль контейнера, а это тоже адский труд :)

dvrbear
07.03.2012, 15:36
вы совершенно правы
в список попадают дети конкретно указанного объекта

тоесть к примеру если я храню яблоки в pole.derevo
а под derevo пападает соседний объект pole.yashik

то указав
var objects:Array = pole.derevo.getObjectsUnderPoint(pt);
в список попадут только яблоки а ящик не затронется
все очень здорово, удобно и грамотно работает

также хочу заметить что стартовые точки объектов должны совпадать (0,0)
илиже потребуется делать перерасчет проверяемой точки
var pt:Point = new Point(mouseX,mouseY);

Wolsh
07.03.2012, 20:05
var pt:Point = pole.derevo.globalToLocal( new Point(stageX, stageY) ); // stageX, stageY - глобальные координаты