Пересечение объектов

То что касается флеша, но не касается ВКонтакте API. Например проблемы при создании прыгающего мячика.

Пересечение объектов

Сообщение Agiliter » 11 сен 2014, 16:05

Добрый день!
Создавая инвентарь, столкнулся с одной проблемой. Но обо всем по порядку. Я создал класс ячейки инвентаря Slot, класс предмета Item и класс InventorySystem. Сам инвентарь и все операции в нем реализованы в классе InventorySystem. Сначала я создаю inventory:Vector.<Slot>, который содержит все ячейки из которых состоит инвентарь, за тем пихаю в ячейки вещи. Всё логично и работает. Хорошо. Я подумал, а почему бы не реализовать drag-and-drop.
Подумал немного и сделал так. В цикле прошелся по всем слотам и прицепил к непустым из них слушатели событий
  1. inventory[i].getItem().addEventListener(ItemEvent.ITEM_PICKED_UP, onItemPickedUp );
  2. inventory[i].getItem().addEventListener(ItemEvent.ITEM_DROPPED, onItemDropped)

Предварительно, разумеется, каждый из Item внутри собственного класса слушает события захвата и отпускания мыши
  1. this.addEventListener(MouseEvent.MOUSE_DOWN, onItemPickedUp );
  2. this.addEventListener(MouseEvent.MOUSE_UP, onItemDropped);

и диспатчит в обработчике
  1. private function onItemPickedUp(e:MouseEvent):void  
  2. {this.dispatchEvent(new ItemEvent(ItemEvent.ITEM_PICKED_UP));}     
  3. private function onItemDropped(e:MouseEvent):void
  4. {this.dispatchEvent(new ItemEvent(ItemEvent.ITEM_DROPPED))}


Соответственно в классе InventorySystem описаны обработчики
  1. protected function onItemPickedUp(e:ItemEvent):void
  2. {
  3.     e.target.startDrag();
  4. }   
  5. protected function onItemDropped(e:ItemEvent):void
  6. {
  7.      ...
  8.      e.target.stopDrag();
  9.      e.target.setCenter(mouseX, mouseY); //Получаем point - координаты центра item
  10.            
  11.      for (var i:int = 0; i < numOfSlots; i++)
  12.      {
  13.     if(inventory[i].hitTestPoint(e.target.getCenter().x, e.target.getCenter().y, false))
  14.     {
  15.         trace("Пересекает ячейку с id: " + i);
  16.                 ...
  17.     }
  18.      }
  19. }   

Всё отлично работает. Специально здесь урезал все операции, чтобы не захламлять код в теме. Но суть итак, думаю, ясна. Я просто перебираю все слоты в inventory[i] и проверяю их на столкновение с центром e.target (т.е. item). В пределах одного инвентаря всё работает отлично.

Но возникла проблема. Мне понадобилось создать два инвентаря и реализовать drag-and-drop между ними. Но я не знаю как проверять столкновение между слотом и предметом в двух разных InventorySystem. Единственное, что пока пришло на ум - это создать два разных массива внутри одного InventorySystem и тогда тупо
  1. if(inventory1[i].hitTestPoint(e.target.getCenter().x, e.target.getCenter().y, false)
  2. if(inventory2[i].hitTestPoint(e.target.getCenter().x, e.target.getCenter().y, false)

Но это ни есть хорошо. Костылей стараюсь избегать. Мне нужен класс, который бы реализовывал инвентарь независимо от того будут там другие инвентари или нет.
С уважением,
М.Ф.
Agiliter

 
Автор темы
Сообщения: 112
Зарегистрирован: 01 фев 2014, 13:46
Благодарил (а): 29 раз.
Поблагодарили: 0 раз.

Чтобы убрать блок с рекламой, зарегистрируйтесь на форуме или войдите.

Google
 



Re: Пересечение объектов

Сообщение XELAD » 11 сен 2014, 16:52

  1. function onItemDropped(e:ItemEvent):void
  2. {
  3.     //...
  4.     e.target.stopDrag();
  5.  
  6.     var arr:Array = [inventory1,inventory2,inventory3,inventory999];
  7.     for each (var t in arr) {
  8.         for each (var i in t) {
  9.             if (i.hitTestPoint(mouseX,mouseY,false)) {
  10.                 trace("Hits", i.name);
  11.             }
  12.         }
  13.     }
  14. }

Использовал i в качестве ссылки на экземпляр, а не в качестве индекса.
XELAD

 
Сообщения: 205
Зарегистрирован: 17 июл 2012, 05:25
Благодарил (а): 13 раз.
Поблагодарили: 24 раз.

Re: Пересечение объектов

Сообщение Agiliter » 11 сен 2014, 17:11

Про each-цикл я знаю. Но, боюсь, вы меня не поняли. Это я могу, умею, практикую. Речь о другом. Обработчик onItemDropped(e:ItemEvent) находится внутри InventorySystem, как и вектор Inventory. Мне нужно проверять пересечение либо перетаскиваемого предмета со слотом, либо слота с точкой-центром предмета. Для этого я проверяю: Слот.hitTestPoint(центр предмета).

Однако, возникла проблема, когда я создаю два InventorySystem:
var inventory1:InventorySystem= new InventorySystem();
var inventory2:InventorySystem= new InventorySystem();

В каждом из них свой вектор, содержащий слоты ( inventory:Vector.<Slot>). При этом внутри inventory1 и inventory2 по отдельности предметы перемещаются все хорошо, а вот когда мне нужно перетащить из слота, принадлежащему к inventory1, в слот, принадлежащий inventory2, я не знаю как отслеживать перемещение пересечений.
С уважением,
М.Ф.
Agiliter

 
Автор темы
Сообщения: 112
Зарегистрирован: 01 фев 2014, 13:46
Благодарил (а): 29 раз.
Поблагодарили: 0 раз.

Re: Пересечение объектов

Сообщение XELAD » 13 сен 2014, 22:43

Как я понял: вы создаёте N инвентарей, но каждый не знает другого, у каждого свой обработчик.
Создаёте
static private var <имя>:Array = new Array();
в классе InventorySystem, который будет хранить ссылки на все ваши инвентари.
В public function InventorySystem добавляете строку
<имя>.push(this);
Перетащили предмет, прошлись вышеуказанной функцией по всем имеющимся инвентарям (записаны в <имя>), удалили из инвентаря A предмет, добавили в слот инвентаря B.

За это сообщение автора XELAD поблагодарил:
Agiliter
XELAD

 
Сообщения: 205
Зарегистрирован: 17 июл 2012, 05:25
Благодарил (а): 13 раз.
Поблагодарили: 24 раз.


Вернуться в Программирование на Flash



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0