![]() |
Группировка объектов
Доброго времени суток.
Столкнулся с задачей сгруппировать объекты на сцене, чтобы их можно было вместе растягивать, крутить и перемещать. И в принципе есть два решения : 1) Засовывать их в новый Sprite. Это облегчит существенно процесс вращения и растягивания, но для того чтобы добавить элемент в группу, нужно будет его "изъять" со сцены (заморочка с add(remove)Element / add(remove)Child во флексе) и добавить в мувик, при этом подгонять ему новые координаты чтобы визуально он остался на той же позиции. А в случае с вложенными группами это может превратиться в нехилый геморрой. Также что касается растягивания (поэкспериментировал со спрайтами) , то тоже всё автоматом будет сжиматься / растягиваться. 2) Объединять их в группы с помощью ассоциативных массивов. Т.е. каждому элементу задать свой groupID, и при клике на него, выделять всю группу (перетаскивать / вращать итд). Существенно упрощает работу с координатами, в принципе я реализовал в этом случае всё кроме вращения. Но при вращении придётся вращать каждый элемент вокруг своей оси и вокруг центра тяжести группы (который можно будет перетаскивать), что обещает доставить немало хлопот. При растягивании придётся учитывать смещение по x и y и изменение ширины/высоты. Кроме того, при операциях с целой группой придётся в цикле проматывать все элементы : скажем, при перетаскивании придётся обновлять координаты всех элементов группы, и элементов вложенных групп, итд. У меня вопрос - какой из вариантов будет жрать меньше ресурсов? Конечно многое зависит от реализации, но всё же? И может есть третий вариант, который намного проще и я попусту бьюсь головой об батарею ? Заранее спасибо. |
Цитата:
Цитата:
В вашем случае правильное решение не заботится пока о быстродействии отрисовки, но принять меры для возможности замены способа отображения (спрайт или отедльные спрайты на экране) без изменения остальной логики. Простыми словами, отделить Model+Controller от View. Model от изменения способа отображения у вас измениться не должен. А потом уже по месту решать, что делать со view. Цитата:
Все ваши действия делаются элементарным домножением слева на матрицу трансформации. Т.е. была у объекта матрица Mo, стала Mt*Mo, где Mt - матрица преобразования. Для поворотов/сдвигов строится легко. Для перекоса (skew) повернутой группы (в координатах группы) чуть-чуть сложнее (добавится обратная матрица текущего преобразования группы). Соответственно, если у вас объекты собраны в одну группу, умножается только матрица группы. Если разобрана - матрицы отдельных элементов группы. Mt в этом случае - одна для всех таких элементов вне зависимости от вложенности! Ну и на всякий случай - никакой магии там нет. Эффективная матрица для объектов в группе строится путем умножения на внешние матрицы групп :). Т.е. в одном случае у вас было Mg1*Mg2*Mob=Mobj1 (g1, g2 - группы, Mob- матрица трансформации объекта в группе g2, Mg2 - трансформация группы g2 относительно g1, Mg1 - трансформация g1 относительно сцены, Mobj1 - трансформация объекта относительно сцены). Очевидно, что из этого следует, что (Mt*Mg1)*(Mg2*Mob)=Mt*(Mg1*Mg2*Mob)=Mt*Mobj1, так что с точки зрения чистой математики без разницы, кого на что домножать. С точки зрения реализации я бы хранил отдельные матрицы трансформации для групп и объектов внутри группы. Для визуализации - как угодно. Можно складывать в спрайты (может быть, ставить им cacheAsBitmap). Можно раскладывать индивидуальные листья, вычисляя эффективную матрицу. Для трансформаций есть небольшое отличие, связанное с точностью вычислений. При использовании индивидуальных матриц из-за потери точности объекты внутри группы могут начать "разъезжаться" относительно друг друга. Т.е. после какого-то количества поворотов, например, квадрат перекосится. Причем вернуть объекты "в исходное состояние" уже не получится. А в группе (с отдельной матрицей) можно будет сбросить трансформацию группы и объекты станут квадратными. Хотя вы артефакты из-за точности вряд ли заметите, чтобы что-то накопилось, нужно быть или очень везучим (чтобы сразу создать матрицу трансформации, которая даст артефакт), или очень долго и нудно крутить объект (миллионы и миллиарды раз). Всякие rotation/scaleX/scaleY/x/y у визуального объекта вам не нужны. Совсем. Вам нужны матрицы. При желании преводить координаты из одних систем в другие (ну мало ли где нужно, для вывода на экран, например) используются те же матрицы преобразования объектов. В матрицах все прекрасно пишется и работает. Прием все операции (повотот, сдвиг, масштабирование, перекос (skew)) - все это домножения на матрицы, только матрицы разные. Соответственно, выбор и формирование матрицы делается при выборе операции, а затем на модель просто применяется операция (applyTransform(Matrix), например). |
Ну архитектура моего приложения скорее MVP чем MVC.
А что касается матриц, ведь всё кроме skew и shear можно осуществить элементарным rotation / x / y / scale. Вы видимо объяснили мне как растягивать пропорционально целую группу элементов, но я так и не понял : К примеру растягиваем группу с width 200 и height 300 так что в итоге её width изменяется на 10, height на 20. Какую матрицу применить ко всем элементам этой группы чтобы они также пропорционально растянулись ? Сделал но при scaleX и Y текстовых полей текст искажается ( в растре) / меняет размер шрифта (в векторе) |
Конкретная архитектура не слишком принципиальна. Главное, чтобы вид был отделен от модели и его было просто поменять. Матрицами проще работать, чем scale/x/y/rotation. Через них все преобразования делаются единообразно и комбинации преобразований тоже легко выражаются. Через x/y/scale/rotation повотор вокруг произвольной точки, например, не так просто делается (для уже повернутого объекта).
Со скейлом все просто. Пусть мы скейлим относительно точки x, y. Тогда матрица будет Код:
|1 0 x| |sx 0 0| |1 0 -x|С текстом не совсем понятно, что именно вы хотите. Я бы как раз ожидал, что после скейла текст пропорционально уменьшится вместе со всеми остальными объектами группы. А иначе я нарисую кнопку, поскейлю, и она разъедется. Хотя вообще это тоже не большая проблема. Тоже решается матрицами :). Пусть Mf - эффективная матрица текстового поля (либо просто матрица, либо произведение всег групп на собственную матрицу, если работать с раздельными матрицами). Тогда вычисляем "систему координат" текстового поля в экранных координатах. Код:
|1| |0| |0| |0| |x' 0 0| |
| Часовой пояс GMT +4, время: 08:41. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.