PDA

Просмотр полной версии : Сортировка отображения


taluks
12.09.2013, 01:14
как сделать что бы нормально отображались объекты и не дергались деревья ?(видео ниже)
objects.sortOn("y");
for each (var obj:DisplayObject in objects)
addChild(obj);
получается вот это (видео) (http://youtu.be/N07O1Mr9XL8)

in4core
12.09.2013, 02:34
в коде ошибки нет. показывайте весь код

caseyryan
12.09.2013, 06:36
в коде ошибки нет. показывайте весь код
Вообще-то есть. В сортировке не указано, что значение "y" числовое, поэтому сортируется по строкам


objects.sortOn("y", Array.NUMERIC);
var i:int = objects.length;
while (i--) {
var childIndex:int = getChildIndex(objects[i]);
if (childIndex != i) {
setChildIndex(objects[i], i);
}
}

in4core
12.09.2013, 16:43
Вообще-то есть. В сортировке не указано, что значение "y" числовое, поэтому сортируется по строкам Да это уже без разницы, в прикрепленном файле видна перетасовка, анимация и т.п. Здесь же показан частный единчиный случай, в котором такой зависимости быть не может

maxkar
12.09.2013, 16:59
В документации по Array.sortOn (ну и в Array.sort, наверное, тоже) написано, что сортировка не стабильная (not stable). Так что порядок "равных" элементов может меняться.

Выходов два. Либо определить порядок так, чтобы он был стабильным (было меньше "равных" элементов). Либо использовать стабильную сортировку (написать ее руками).

caseyryan
12.09.2013, 16:59
Да это уже без разницы
Разница, как раз таки есть

AlexCooper
12.09.2013, 17:16
arraySort.sort(mySort);

private function mySort(objA:Object, objB:Object) {

if (objA.y<objB.y)
{
return 1;
}
else if (objA.y>objB.y)
{
return -1;
}
else
{
return 0;
}
}

for ( var newDepth:uint=0; newDepth<arraySort.length; newDepth++)
setChildIndex(arraySort[newDepth], newDepth);

KumoKairo
12.09.2013, 17:24
По моему можно поменять алгоритм Z - сортировки немного: проверять и менять местами только объект героя и конкретное дерево, а не все объекты друг с другом.

Либо использовать стабильную сортировку (написать ее руками).
Можно просто предоставить другую функцию сортировки, которая проверят и Y и X объекта

objects.sort(myLittleZSorter);
var i:int = objects.length;
while (i--) {
var childIndex:int = getChildIndex(objects[i]);
if (childIndex != i) {
setChildIndex(objects[i], i);
}
}

...
private function myLittleZSorter(a: Object, b: Object): int {
if (a.y > b.y) {
return 1;
} else if (a.y < b.y) {
return -1;
} else if (a.x > b.x) {
return 1;
} else {
return -1;
}
}
Тогда при сортировке не будут скакать элементы с одинаковым УГРИКОМ

in4core
12.09.2013, 19:03
Разница, как раз таки есть Да нет же, нет разницы! Я клоню к тому, что сортировку вообще можно и не делать для того когда, что был приведен. А вот в прикрепленном файле видно, как она будет работать если ее через таймер гонять - так причем тут первый код?* В нем как раз нет разницы, что написать, будет статическая картинка и все, пускай и не перетасованная, дело то не в этом.

P.s. - все там stable

GBee
13.09.2013, 01:15
Вроде как for each не обещает правильный порядок следования

Nooob
13.09.2013, 02:49
Для такой задачи лучше всего подходит сортировка вставками.
Потому что:
1. Высокая скорость на практически отсортированном массиве
2. Сохраняется первоначальный порядок
Время выполнения в худшем случае O(n²), в твоем случае O(n) - O(n + n)


var n:int = objects.length;
for (var i:int = 1; i < n; i++)
{
var base:DisplayObject = objects[i];
for (var j:int = i - 1; j >= 0; j--)
{
var current:DisplayObject = objects[j];
if (current.y > base.y)
{
objects[j + 1] = current;
continue;
}
break;
}
objects[j + 1] = base;
}
for (i = 0; i < n; i++)
{
current = objects[i];
if(current.parent == this)
{
setChildIndex(current, i);
continue;
}
addChildAt(current, i);
}

Babylon
13.09.2013, 07:09
Я бы сначала проиндексировал объекты. Отсортировал по индексам
А сами объекты расставил бы только после сортировки по индексам.

expl
13.09.2013, 13:31
Вроде как for each не обещает правильный порядок следования
Для массивов и векторов обещает
А для ключей динамических объектов и Dictionary - вообще никто не обещает

Время выполнения в худшем случае O(n²), в твоем случае O(n) - O(n + n)
Я бы так смело оценки не занижал - нет уверенности, что setChildIndex отрабатывает за 1-ное время.

Хотя, на практике, обычно я видел похожие подходы, где двигается небольшое количество объектов на фоне сотен статичных.
Перемещаются они не на много - и в итоге срабатывает даже не O(n)(что было бы много), а 0-2 шага на персонажа
(хотя там так же не понятно, на сколько портит картину неединичная сложность работы AddChildAt, SetChildIndex и т.п.)
Но там промежуточный массив полностью не прогонялся ни в коем разе, просто при перемещении объекта смотрели, куда его переместить (выше или ниже) и искали место вставки в этом направлении - получалось мало шагов. При добавлении нового или при создании карты только большие нагрузки.

Это всё работало, если статичных объектов было на порядок больше динамических и они должны были участвовать в сортировке.