Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Сортировка объектов по глубине (http://www.flasher.ru/forum/showthread.php?t=137450)

Universe 13.03.2010 23:55

Сортировка объектов по глубине
 
Привет!Есть вопрос - как отсортировать объекты, по глубине на основе их положения по вертикали? Т.е. создать некий эффект перспективы - чем выше объект - тем дальше он по глубине. Вся трудность состоит в том, что объекты генерируются случайным образом и координаты каждого нового объекта не известны!

AlexDesinger 14.03.2010 01:19

Привет! Есть ответ - сначала узнать координаты нового объекта, затем расположить его по координате z на нужную глубину и применить z-sorting, в нете полно примеров халявных классов!

TERRORist 14.03.2010 01:37

Цитата:

Сообщение от Universe (Сообщение 892943)
координаты каждого нового объекта не известны!

Задачка достойная академиков... Сортировка по неизвестным параметрам - нелегкая задача

gloomyBrain 14.03.2010 02:42

Цитата:

объекты генерируются случайным образом и координаты каждого нового объекта не известны
Координаты не известны до создания объекта. После того, как он создан - у него просто обязаны быть координаты (если он наследует DisplayObject)

mikhailk 14.03.2010 10:44

1. Все объекты при создании загоняются в массив
2. Создаем новый объект (но не выводим на сцену) и тоже кладем в массив
3. Сортируем массив (чтобы индексы соответствовали порядку показа по z)
4. Показываем созданный объект - он появится как надо

Universe 15.03.2010 12:27

To mikhailk:
Получается надо создать 2 массива?
А что если создать 1 массив с объектами, которые необходимо размещать, а второй - с координатами этих же объектов по оси Y? Получается тогда нужно сортировать уже второй массив при помощи sort(16)? А значения индексов присваивать элементам первого массива - arr1.setChildIndex(arr1[i], arrY[i])...как то так?

AlexDesinger 15.03.2010 12:52

а можно вопрос? Вы какого именно эффекта хотите добиться? Вот такой подойдет -
http://kosulin.ru/newsite/newsite.html#/graphics ?

mikhailk 15.03.2010 22:16

массив один

Код AS3:

public function zSort(e:Event):void {        
        personages.sortOn(['y','name'],[Array.NUMERIC,Array.DESCENDING]);
        var l:int = personages.length;
        while (l--) {
                var o:DisplayObject = personages[l] as DisplayObject;
                if (containerObjects.getChildAt(l) != o) containerObjects.setChildIndex(o, l);
        }
}

В примере personages - массив мувиков, болтающихся по сцене, containerObjects - контейнер, в котором они все находятся.

dimarik 15.03.2010 22:30

Цитата:

Сообщение от mikhailk (Сообщение 892973)
1. Все объекты при создании загоняются в массив
2. Создаем новый объект (но не выводим на сцену) и тоже кладем в массив
3. Сортируем массив (чтобы индексы соответствовали порядку показа по z)
4. Показываем созданный объект - он появится как надо

Все объекты у Вас имеют x = y = 0; (по умолчанию); Как Вы собираетесь их сортировать? Хотя, можно сортировать по размерам ). А может мы просто не знаем Ваших критериев сортировки. Объясните.

mikhailk 16.03.2010 01:02

Если я правильно понял автора с его вопросом, то объекты генерятся и случайным образом помещаются на сцену. Т.е., координаты у них есть (а как иначе?), просто не известны заранее.

Функция zSort (принадлежит не мне, я лишь добавил сортировку по name, чтобы убрать мерцание двух объектов с одним y) запускается по событию enterFrame или по таймеру. Новый объект после генерации падает в массив и включается в сортировку. Вот дополнительно к коду функции zSort (чтобы было понятно, как заполняется массив для сортировки):

Код AS3:

  var personage = new Personage();
  personage.x = int(Math.random())*500;
  personage.y = int(Math.random())*400;
  containerObjects.addChild(personage);
  personages.push(personage);


gloomyBrain 16.03.2010 01:08

Цитата:

enterFrame или по таймеру
Неа. Запускать надо при добавлении нового объекта или изменении координат существующего. Причем если несколько объектов поменяли координаты за один кадр - запускать все-равно один раз для одного кадра.
Я бы сделал объектам внутренний листенер события Event.ADDED_TO_STAGE, внутри которого диспатчил бы некое свое событие (или то самое ADDED_TO_STAGE, не суть). И вот это свое событие уже ловил бы в контейнере и запускал по нему сортировку.

mikhailk 16.03.2010 13:43

ну да
это если изменения нерегулярны
а если объекты все время ползают по сцене?

и чем отличается запуск по enterFrame от запуска один раз для одного кадра? ))

Впрочем, зависит, конечно, от того, сколько объектов у автора и насколько они сложные.

gloomyBrain 16.03.2010 16:29

Цитата:

чем отличается запуск по enterFrame от запуска один раз для одного кадра? ))
Ясно из вопроса - ENTER_FRAME = всегда один раз на кадр, CUSTOM_EVENT = не чаще, чем один раз на кадр

Котяра 16.03.2010 16:37

таймер может вызываться чаще чем энтерфрейм, причём можно в хэндлере таймера сделать
Код AS3:

event.updateAfterEvent()


Bgg 21.04.2010 14:12

Начал сортировать объекты по z не дочитав документацию. В итоге при большом количестве объектов визуально x и y начинают меняться. Как нибудь это можно избежать?

ps childIndex в моем случае не подходит.


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

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