проверка на hitTest , для большого количества объектов @ DeForum.ru
DeДверь  
Логин:  
Пароль:  
  Автологин  
   
Разместить рекламу
Письмо админу
Правила | FAQ | *Поиск | Наша команда | Регистрация | Вход
 
 
 Страница 1 из 1 [ Сообщений: 27 ] 
*   Список форумов / Технологии изображения / Flash » ответить » создать топик « | »
Автор Сообщение
Eduard Муж.
участник
61
Сообщения: 1629
Зарегистрирован: 24.09.03
Откуда: St.Petersburg , Moscow
Заголовок сообщения: проверка на hitTest , для большого количества объектов
Сообщение Добавлено: 4 Февраль 2006, 18:32:33 
подскажите как сделать :

Надо чтобы клип_A проверял стлакивается ли он в данный момент с другим клипом(ми)_B незная их имен ?
Если получить имя клипа_B сталкивающегося c клипом_A ,а затем делать проверку на часть имени клипа_B , такое возможно ?

(это для сцены на которой например может быть около 20 клипов_A и 50 клипов_B , поэтому я думаю нельзя использовать для проверки циклы в коде на клипах , если только код не каждый момент времени работает)

и еще , подскажите код : если первые 4 символа имени клипа == "abcd"
bE(o0L Муж.
постоянный участник
23
Сообщения: 3311
Зарегистрирован: 22.07.03
Откуда: сзабугра
Сообщение Добавлено: 4 Февраль 2006, 21:10:42 

Цитата:
а затем делать проверку на часть имени клипа_B , такое возможно ?

конечно
if(clip._name.substr(0,4)=='abcd')trace('totsamijklip');// :)

_________________
можно на ТЫ.
Король Муж.
участник
18
Сообщения: 1352
Зарегистрирован: 24.07.04
Сообщение Добавлено: 4 Февраль 2006, 21:11:34 
путь["abcd"+переменная] - твой мув
остальную часть вопроса не понял совсем. чтоб "получить имя клипа_B сталкивающегося c клипом_A " нужно уже знать их имена, к чему проверка частей имен?

_________________
Здравствуй, Олимпийский!
bE(o0L Муж.
постоянный участник
23
Сообщения: 3311
Зарегистрирован: 22.07.03
Откуда: сзабугра
Сообщение Добавлено: 4 Февраль 2006, 21:14:27 
потому что у парня могут быть 50 клипов с именами vazhnij_clip_1 , vazhnij_clip_2 и так далее.
вот он и хочет из всего хаоса узнать именно эти клипы, незная их id.
чё тут не понятного то?

_________________
можно на ТЫ.
Мигель Муж.
участник
75
Сообщения: 1453
Зарегистрирован: 09.01.04
Откуда: http://design-cafe.ru
Сообщение Добавлено: 4 Февраль 2006, 21:21:11 
Не совсем понятен вопрос ))

Однако может быть поможет то, что все клипы являются как бы элементами ассоциативного массива _root - и возможен любой перебор всех элементов.
Имя клипа можно получить через eval

вот к примеру -

Код:
tester.startDrag(true);
tester.onEnterFrame = function () {
   for(inst in _root) {
      
      if (tester.hitTest(_root[inst])) {
      
      trace(eval(_root[inst]));}}}

_________________
_____
Работа Изображение Работы Изображение О Работе
Мигель Муж.
участник
75
Сообщения: 1453
Зарегистрирован: 09.01.04
Откуда: http://design-cafe.ru
Сообщение Добавлено: 4 Февраль 2006, 21:22:41 
Правда при таком раскладе тут хитТест на самого себя срабатывает, но при должной сноровке и это излечимо

_________________
_____
Работа Изображение Работы Изображение О Работе
bE(o0L Муж.
постоянный участник
23
Сообщения: 3311
Зарегистрирован: 22.07.03
Откуда: сзабугра
Сообщение Добавлено: 4 Февраль 2006, 21:32:28 
Мигель, ты (я надеюсь) понимаешь сколько это будет жрать ресурсов? учитывая что у _root. помимо клипов дофига всякого. ;)

P.s.
Если Eduard, хочет сделать частицы с collision то делается это совершенно подругому, нежели hitTest()

_________________
можно на ТЫ.
Eduard Муж.
участник
61
Сообщения: 1629
Зарегистрирован: 24.09.03
Откуда: St.Petersburg , Moscow
Сообщение Добавлено: 4 Февраль 2006, 22:06:30 

bE(o0L писал(а):
if(clip._name.substr(0,4)=='abcd')trace('totsamijklip');// :)

:beer:


bE(o0L писал(а):
Если Eduard, хочет сделать частицы с collision то делается это совершенно подругому, нежели hitTest()

а как ? пространство делят на зоны , сетку ?
Eduard Муж.
участник
61
Сообщения: 1629
Зарегистрирован: 24.09.03
Откуда: St.Petersburg , Moscow
Сообщение Добавлено: 4 Февраль 2006, 22:10:18 
Мигель, огромное спасибо !!!
Король Муж.
участник
18
Сообщения: 1352
Зарегистрирован: 24.07.04
Сообщение Добавлено: 4 Февраль 2006, 22:43:24 
bE(o0L, ну ты тут телепат, что ж поделать...

_________________
Здравствуй, Олимпийский!
BlooDHounD Муж.
соучастник
0
Сообщения: 585
Зарегистрирован: 12.03.04
Откуда: Беларусь - Борисов
Сообщение Добавлено: 5 Февраль 2006, 02:03:02 
Мигель, во флэше нет такіх массивов ;) можно создать свойство, но сделать массив ассоциативным нельзя :)
Король Муж.
участник
18
Сообщения: 1352
Зарегистрирован: 24.07.04
Сообщение Добавлено: 5 Февраль 2006, 02:15:57 
помнится - как то я сказал примерно то же самое про массивы на флешере - после чего мне указали на то что я неправ -кому верить?

_________________
Здравствуй, Олимпийский!
bE(o0L Муж.
постоянный участник
23
Сообщения: 3311
Зарегистрирован: 22.07.03
Откуда: сзабугра
Сообщение Добавлено: 5 Февраль 2006, 08:47:26 
Eduard,
да не
я например пишу класс (extend MovieClip) который обрабатывает позицию клипа относительно других клипов.
примерно 30-40 клипов великолепно скачут без тормозов.
дальше - хуже

_________________
можно на ТЫ.
Мигель Муж.
участник
75
Сообщения: 1453
Зарегистрирован: 09.01.04
Откуда: http://design-cafe.ru
Сообщение Добавлено: 5 Февраль 2006, 16:45:52 
BlooDHounD, На флеше ЕСТЬ ассоциативный массив, и яркий тому пример это система клипов на _root.
А так же можно создать и свой массив, в котором вместо числовых индексы будут индексы стринговые.
Пример почти из книжки

designers = new Array(3);
designer["web"] = "vasia Pupkin";
designer["3d"] = "Kolia Vasechkin";
designer["pack"] = "Ogly Beldiev";

И это массив. Ассоциативнй. И это работает.
Конечно можно занырнуть в глубины других ООП языков и сказать, что это все еррунда, а не ассоциативный массив, но это вопросы терминологии и теории. Колин Мук почему то посчитал, что объекты - это ассоциативные массивы, а если копнуть еще глубще - то у флеша вообще нет массивов, а есть объекты ))) Главное, что на практике это работает, а здесь я что то не заметил ярых приверженцев теоретического прграммирования )) :beer:


bE(o0L, конечно понимаю, код ДАЛЕКО не оптимальный )) Но в
этом случае вложенные клипы не будут просматриваться, если внимательно посмотреть код, можно увидеть что здесь нет рекурсии, а только при рекурсии можно просканировать все клипы, даже со вложенными. Возможно грамотнее все эти клипы проще было бы вложить в один муви клип и сканировать их именно там. Кстати так он и самого себя не будет хитТестить.

_________________
_____
Работа Изображение Работы Изображение О Работе
Eduard Муж.
участник
61
Сообщения: 1629
Зарегистрирован: 24.09.03
Откуда: St.Petersburg , Moscow
Сообщение Добавлено: 5 Февраль 2006, 18:04:08 
Мигель, а зачем там EVAL ? код и без него работает
Мигель Муж.
участник
75
Сообщения: 1453
Зарегистрирован: 09.01.04
Откуда: http://design-cafe.ru
Сообщение Добавлено: 5 Февраль 2006, 18:07:09 
действительно )) не знаю, зачем )) как то по иннерции... Никогда им не пользуюсь...

_________________
_____
Работа Изображение Работы Изображение О Работе
BlooDHounD Муж.
соучастник
0
Сообщения: 585
Зарегистрирован: 12.03.04
Откуда: Беларусь - Борисов
Сообщение Добавлено: 6 Февраль 2006, 01:51:47 
Мигель, zво флэше нету таких массивов :) яркий тому пример это твои заблуждения :)
Так как во флэше Array наследуется от Object, как ты уже заметил. И как назвал это Мук, меня не волнует. Вопросы сравнения и вопросы терминологии - это разные вопросы.
Цитата:
designers = new Array(3);
designer["web"] = "vasia Pupkin";
designer["3d"] = "Kolia Vasechkin";
designer["pack"] = "Ogly Beldiev";

код бредовый :)
Код:
designers = new Array(3); // этой строкой ты создал 3 элемента массива
trace(designers); // Output: undefined,undefined,undefined

Код:
designer["web"] = "vasia Pupkin";
designer["3d"] = "Kolia Vasechkin";
designer["pack"] = "Ogly Beldiev";
этими строками создал 3 свойства :)

В обўем можно было просто сделать Object и не мучать Array ;)

А слова Мука ты просто неправельно понял :)
Eduard Муж.
участник
61
Сообщения: 1629
Зарегистрирован: 24.09.03
Откуда: St.Petersburg , Moscow
Сообщение Добавлено: 6 Февраль 2006, 15:47:47 
а возможно ли сделать так : в цикле перебирать клипы в сцене , и затем проверять с чем они соприкасаются ?
вобщем чтобы по очереди …
Eduard Муж.
участник
61
Сообщения: 1629
Зарегистрирован: 24.09.03
Откуда: St.Petersburg , Moscow
Сообщение Добавлено: 6 Февраль 2006, 22:16:54 
попробывал такую конструкцию :
Код:
for (clip in land) {
if (clip==…) {
for (object in clip) {
if (object==…) {unloadMovie(object); break;}
}

проблема в том что после unloadMovie , цикл (...in...) всеравно его видит. В чем причина ?
_iv Муж.
Модератор
32
Сообщения: 166
Зарегистрирован: 26.10.05
Откуда: Москва
Сообщение Добавлено: 7 Февраль 2006, 03:25:50 
Eduard, проверка столкновения большого количества объектов вопрос довольно серьезный
и прежде всего тем, что как правило это нужно делать без тормозов.

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

- выносить из циклов ненужные вычисления;
- заменять множественные вычисления объектов на ссылки;
- ограничивать циклы обхода только нужными объектами;

например, исходный код:
Код:
for (var i in this._parent) {
  if (this._parent[i] != this) {
    if (this.hitTest(this._parent[i])) {
      trace("hit: "+this._parent[i])
    }
 }
}

оптимизированный:
Код:
//создаем объект-хранитель ссылок на мувиклипы, участвующие в проверке на столкновения:
_global.movies_obj = {}; // _global не лучшее место, но для примера сойдет.

// при создании мувиклипа добавляем ссылку на него в неком объекте:
_global.movies_obj[this._name] =this;

// далее, в методе проверки:
var m_obj= _global.movies_obj; //

// в методе проверки вначале удаляем себя из этого объекта:
delete movies_obj[this._name];
for (var i in m_obj) {
  var mc = m_obj[i];
    if (this.hitTest(mc)) {
      trace("hit: "+mc)
   }
}
m_obj[this._name] = this; // а при выходе возвращаем.

- таким образом мы убрали одну проверку
Код:
if (this._parent[i] != this) {

- плюс к тому, мы заменили 3 вычисления мувиклипа:
Код:
this._parent[i]
на одно:
Код:
var mc = movies_obj[i];

и в дальнейшем использовали готовую ссылку;
- мы ограничили цикл обхода только нужными объектами
обходя не this._parent, в котором по идее может оказаться что угодно
а специальный объект, содержащий ccылки только на нужные мувики.

если объектов очень много, то возможно будет полезным реализовать
разбиение на сектора и последующее уточнение.
что это значит?
например можно на фоне создать прозрачные мувиклипы-секторы.
затем обежать их и, если обнаружится пересечение, то добавить мувик в список
конкретного сектора.
и только затем делать проверку на пересечение используя конкретные объекты-сектора.

Код:
this.sectors_mc.broadcastMessage("onClearSectorsList"); // очищаем лист секторов
//
this.hit_movies.broadcastMessage("onMoveObjects"); // передвигаем мувики
this.hit_movies.broadcastMessage("onCheckHits"); // проверяем пересечения

// это в секторах
function onClearSectorsList() {
  this.hits_container = {}
}

// это в движущихся мувиках:
function onMoveObjects () {
  this._x+= this.xspeed;
  this._y+= this.yspeed;
  this.hit_list_of_sectors = {}
  var sectors = this._parent._parent.sectors_mc;
  for (var i in sectors) {
    var sector_mc = sectors[i]
    if (this.hitTest(sector_mc)) {
      sector_mc.hits_container[this._name] = this;
      this.hit_list_of_sectors[sector_mc._name] = sector_mc
    }
  }
}

function onCheckHits () {
   for (var i in  this.hit_list_of_sectors) {
     var hits_object = this.hit_list_of_sectors
     delete hits_object[this._name]
     for (var k in hits_object) {
        var mc = hits_object[k]
        if (this.hitTest(mc)) {
           // дальнейшая проверка
        }
     }
     hits_object[this._name] = this;
  }
}


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

вот этот код дал 4х кратное увеличение производительности:
(нужно создать и залинковать в либе мувик с именем Ball_mc, в нем нарисовать квадратик
этот код втыкаем просто в руте в первый и единственный кадр)
Код:
this.setBallClass = function() {
   delete this.setBallClass;
   var Ball = function () {
      this.init();
   };
   AsBroadcaster.initialize(Ball);
   Ball.onMessage = function() {
      this.broadcastMessage.apply(this, arguments);
   };
   var compareFunction = function (a, b) {
      return a._x>b._x ? 1 : a._x<b._x ? -1 : 0;
   };
   Ball.checkHits = function() {
      this._listeners.sort(compareFunction);
      var first_mc = this._listeners[0];
      for (var i = 1, length = this._listeners.length; i<length; i++) {
         var next_mc = this._listeners[i];
         if (first_mc.hitTest(next_mc)) {
            first_mc.highlight();
            next_mc.highlight();
         }
         first_mc = next_mc;
      }
   };
   //
   Object.registerClass('Ball_mc', Ball);
   Ball.prototype.__proto__ = MovieClip.prototype;
   //
   var tmp = Ball.prototype;
   tmp.init = function() {
      Ball.addListener(this);
      this._xscale = this._yscale=50+_global.Math.random()*50;
      this.radius = this._width/2;
      this._x = this.radius+(Stage.width-this._width)*_global.Math.random();
      this._y = this.radius+(Stage.height-this._height)*_global.Math.random();
      this.x_speed = Math.ceil(_global.Math.random()*10-5) || 1;
      this.y_speed = Math.ceil(_global.Math.random()*10-5) || 1;
      this.cacheAsBitmap = true;
   };
   tmp.onMove = function() {
      var clr = new Color(this);
      clr.setRGB(0xCCCCCC);
      this._x += this.x_speed;
      this._y += this.y_speed;
      if ((this._x+this.radius)>Stage.width || (this._x-this.radius)<0) {
         this.x_speed = -this.x_speed;
      }
      if ((this._y+this.radius)>Stage.height || (this._y-this.radius)<0) {
         this.y_speed = -this.y_speed;
      }
      /*
      var p = this._parent;
      for (var i in p) {
         var mc = p[i];
         if (mc != this) {
            if (this.hitTest(mc)) {
               this.highlight()
            }
         }
      }
      // */
   };
   tmp.highlight = function() {
      var clr = new Color(this);
      clr.setRGB(0xFF0000);
   };
   _global.Ball = Ball;
   ASSetPropFlags(_global, 'Ball', 7, 1);
};
this.setBallClass();
// -----------------------------
this.createEmptyMovieClip("balls_mc", 0);
for (var i = 0; i<50; i++) {
   this.balls_mc.attachMovie("Ball_mc", "ball"+i+"_mc", i);
}
// ----------------------
this.onEnterFrame = function() {
   var t = getTimer();
   Ball.onMessage("onMove");
   Ball.checkHits();
   trace(getTimer()-t);
};

чтобы сравнить производительность, нужно закомментировать строку Ball.checkHits();
и раскоментировать закомментированные строки.

ну, полагаю, пока достаточно.
будут вопросы - вэлкам.

вообще, тема определения пересечений достаточно широка и нужно смотреть в каждом
конкретном случае что можно применить для увеличения производительности.
_iv Муж.
Модератор
32
Сообщения: 166
Зарегистрирован: 26.10.05
Откуда: Москва
Сообщение Добавлено: 7 Февраль 2006, 03:30:31 

Eduard писал(а):
проблема в том что после unloadMovie , цикл (...in...) всеравно его видит. В чем причина ?


- причина в том, что в цикл for... in... сразу насыпается весь стэк и обновляется только после выхода.
Eduard Муж.
участник
61
Сообщения: 1629
Зарегистрирован: 24.09.03
Откуда: St.Petersburg , Moscow
Сообщение Добавлено: 7 Февраль 2006, 08:33:04 
_iv, спасибо! :beer: , пойду разбираться с этими скриптами :)
@st@l@vist@
участник
70
Сообщения: 1606
Зарегистрирован: 20.03.03
Откуда: St.Petersburg
Сообщение Добавлено: 7 Февраль 2006, 14:42:33 
Eduard, иногда стоит смотреть по сторонам :)
Начать можно от сюда : http://www.macromedia.com/devnet/flash/ … ids07.html
После чего, найти еще тысячи ресурсов посвященных этому же :)

p.s.: Что касается unloadMovie - попробуй понять разницу между этой командой и removeMovieClip …
eddy444 Муж.
Модератор
315
Сообщения: 14467
Зарегистрирован: 05.05.03
Откуда: NSK
Сообщение Добавлено: 7 Февраль 2006, 14:55:04 
@st@l@vist@, дык какая всетаки разница?
@st@l@vist@
участник
70
Сообщения: 1606
Зарегистрирован: 20.03.03
Откуда: St.Petersburg
Сообщение Добавлено: 7 Февраль 2006, 15:02:56 
createEmptyMovieClip("mc", 1);

trace(mc);
mc.unloadMovie();
trace(mc);
mc.removeMovieClip();
trace(mc);

unloadMovie - не удаляет контейнер (клип), а лишь выгружает его содержание …
Eduard Муж.
участник
61
Сообщения: 1629
Зарегистрирован: 24.09.03
Откуда: St.Petersburg , Moscow
Сообщение Добавлено: 7 Февраль 2006, 17:33:29 
@st@l@vist@ спасибо , а я по привычки unloadMovie() использовал :lamer: , а пример с астероидами все же не на hitTeste основан , учитывая еще какой там код на выстрел вешается , и думаю будет сильно тормозить при моих 50 клипах-выстрелах.
@st@l@vist@
участник
70
Сообщения: 1606
Зарегистрирован: 20.03.03
Откуда: St.Petersburg
Сообщение Добавлено: 7 Февраль 2006, 18:11:51 
Eduard, зачем я тебе линк давал? :) - прочти, что пишут про hitTest и математический рассчет столкновений - это раз.
А два - это, ну не могут убить 50 объектов твою игру, небось просто накосячил где-то ;)

Посмотри частицы на Bit-101, там по 300 штук летает и ничего, не тормозит …
*   Список форумов / Технологии изображения / Flash « | » » ответить » создать топик
 Страница 1 из 1 [ Сообщений: 27 ] 
Показать сообщения за:   Поле сортировки  
Найти:
Перейти:  
Уровень доступа: Вы не можете начинать темы. Вы не можете отвечать на сообщения. Вы не можете редактировать свои сообщения. Вы не можете удалять свои сообщения. Вы не можете добавлять вложения.
cron


ООО ДеФорум
При использовании материалов сайта ссылка на DeForum.ru — обязательна.
Проект Павла Батурина ©2001-2077; // Powered by phpBB © 2013 phpBB Group
Rambler's Top100