![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|
|
|||||
|
Добрый день.
Пожалуйста, помогите советом или кодом. Есть объекты (для простоты квадратики) со свойствами row (строка) col (столбец). Для упрощения пусть сторона квадратов равна 1. Координаты соответствуют x=row, y = col. Все объекты помещены в массив arr: arr[0] = {row:0, col:0}; arr[1] = {row:0, col:1}; … arr[8] = {row:2, col:3}; Объекты (квадраты) располагаются строго в сетке и по периметру некого прямоугольника. Как мне переместить объекты в соответствии с прилагаемым рисунком? Как бы провернуть по часовой стрелке по методу (функции). Свой код не привожу, так как все равно не рабочий. А суть сводил к тому, что пытался получить массив новых индексов и присвоить объектам координаты прежних кубиков. Так как размер фигуры из квадратиков может быть произвольный, то универсальность не получалась. Буду рад любому совету. Спасибо. |
|
|||||
|
Как-то так:
private function layout(items:Vector.<DisplayObject>, offset:int):void { const cols:int = 4; //количество столбцов const rows:int = 3; //количество строк const colWidth = 10; //ширина столбца const rowHeight = 10; //высота строки var count:int = 0; //счетчик элементов for (var i:int = 0; i < rows; i++) { for (var j:int = 0; j < cols; j++) { if (j > 0 && j < (cols - 1) && i > 0 && i < (rows - 1)) //проверка периметра continue; var item:DisplayObject = items[(offset + count)%items.length]; item.x = colWidth * i; item.y = rowHeight * j; count++; } } } offset — смещение первого элемента. P.S. алгоритм писался сразу в браузере и не проверялся.
__________________
משיח לא בא משיח גם לא מטלפן |
|
|||||
|
Спасибо, идею понял (результат на пикче), попробую подправить.
2:caseyryan. Приведенный в стартопике рисунок красноречивее описания: по часовой стрелке поменять клипы (квадраты в моем случае). Нулевой переходит на место первого, первый на место второго ... ну и так до последнего. |
|
|||||
|
Менял. Порядок в цепочке все равно меняется. Но пример натолкнул на вроде правильный алгортим. Сейчас пишу. Получится - выложу. Алгоритм следующий:
1. Беру нулевой элемент массива и смещаю вправо. 2. Затем следующий в массиве.Если вышел за предел возвращаю на место и смещаю вниз. Работаю со следующим. 3. Если опустился ниже нужного возвращаю и смещаю влево. Работаю со следующим. 4. Вышел за ноль возвращаю назад и поднимаю вверх. Работаю со следующим. 5. Вышел за ноль возвращаю на место. Финиш. |
|
|||||
|
Можно смещать элементы интерполяцией.
package { import flash.display.DisplayObject; import flash.display.Graphics; import flash.display.Sprite; import flash.events.TimerEvent; import flash.geom.Point; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.utils.Timer; public class Rect extends Sprite { private var _rects:Vector.<DisplayObject>; private var _points:Vector.<Point>; //точки прямоугольника private var _lengths:Vector.<Number>; //длины сегментов private var _perimeter:Number; //длина периметра private var _offset:int = 0; //смещение public function Rect() { initialize(4, 4, 20); layout(_offset); var timer:Timer = new Timer(500); timer.addEventListener(TimerEvent.TIMER, animate); timer.start(); } private function animate(event:TimerEvent):void { _offset++; _offset = _offset%_rects.length; layout(_offset); } private function layout(offset:int):void { var count:int = 0; for (var i:int; i < _rects.length; i++) { var pos:Point = getPosition(i / _rects.length); var rect:DisplayObject = _rects[(count + (_rects.length - offset))%_rects.length]; rect.x = pos.x; rect.y = pos.y; count++; } } private function initialize(cols:int, rows:int, size:Number):void { //по-сути нужен индекс последнего элемента cols -= 1; rows -= 1; //создаем элементы _rects = createRects((cols + rows) * 2, size); //точки прямоугольника var p0:Point = new Point(); var p1:Point = new Point(cols * size, 0); var p2:Point = new Point(cols * size, rows * size); var p3:Point = new Point(0, rows * size); //длины сегментов var d0:Number = Point.distance(p0, p1); var d1:Number = Point.distance(p1, p2); var d2:Number = Point.distance(p2, p3); var d3:Number = Point.distance(p3, p0); //длина периметра _perimeter = d0 + d1 + d2 + d3; _points = Vector.<Point>([p0, p1, p2, p3]); _lengths = Vector.<Number>([d0, d1, d2, d3]); } //t - позиция элемента на периметре (0..1) private function getPosition(t:Number):Point { //позиция элемента на периметре в пикселях var pos:Number = _perimeter * t; var result:Point; for (var i:int = 0; i < _lengths.length; i++) { //проверяем в каком сегменте находимся if (pos <= _lengths[i]) { var next:int = i + 1; next = next == _lengths.length ? 0 : next; //loop //возвращаем точку на текущем сегменте result = Point.interpolate(_points[next], _points[i], pos / _lengths[i]); break; } //если сегмент не найден вычитаем из позиции длину сегмента pos -= _lengths[i]; } return result; } private function createRects(quantity:int, size:Number):Vector.<DisplayObject> { var rects:Vector.<DisplayObject> = new Vector.<DisplayObject>(); for (var i:int = 0; i < quantity; i++) { var spr:Sprite = new Sprite(); draw(spr.graphics, 0xcccc00, size); var tf:TextField = new TextField(); tf.autoSize = TextFieldAutoSize.LEFT; tf.text = i.toString(); tf.x = spr.width *.5 - tf.width * .5; tf.y = spr.height *.5 - tf.height * .5; spr.addChild(tf); rects.push(spr); addChild(spr); } return rects; } private function draw(g:Graphics, color:uint, size:Number):void { g.beginFill(color); g.drawRect(0, 0, size, size); g.endFill(); } } }
__________________
משיח לא בא משיח גם לא מטלפן Последний раз редактировалось alatar; 25.02.2013 в 16:22. |
|
|||||
|
Привет alatar! Классное решение.
А я выкрутился так: - Зная длину массива, количество колонок и строк поделил объекты на 4 группы. - 1-ю сдвигал вправо на шаг. - 2-ю вниз. = 3-ю влево. - 4-ю - вверх. var i:int; // Этот блок для примера // нумерую for (i=0; i<10; i++) { this["item" + i].str.text = i; } // создаю массив var arrItems:Array = []; for (i=0; i<10; i++) { arrItems.push(this["item"+i]); } // конец блока имитации // получаю нужные данные var cols:int = 4; var rows:int = 3; var count:int = arrItems.length; var widthANDheight = 40; // метод поворота и пересртировки для следующего поворота function test() { for (i=0; i<cols-1; i++) { arrItems[i].x += widthANDheight; } for (i=count-cols+1; i<count; i++) { arrItems[i].x -= widthANDheight; } for (i=cols; i<cols+rows; i+=2) { arrItems[i].y -= widthANDheight; } for (i=cols-1; i<cols+rows-1; i+=2) { arrItems[i].y += widthANDheight; } arrItems.sortOn(["y", "x"], [Array.NUMERIC, Array.NUMERIC]); } |
|
|||||
|
а вот может совсем по-простому
двигаем элементы в массиве по кольцу, а координаты определяем из текущего индекса для конкретного прямоугольника 4х3 public class Main extends Sprite { private var size:Number = 20; private var items:Array; public function Main():void { var initList:Array = [0, 1, 2, 3, 5, 9, 8, 7, 6, 4]; items = []; for (var i:int = 0; i < initList.length; i++) { var item:TextField = new TextField(); item.width = size; item.height = size; item.border = true; item.text = initList[i].toString(); items.push(item); addChild(item); } //items.push(items.shift());// туда items.unshift(items.pop());// сюда update(); } private function update():void { for (var i:int = 0; i < items.length; i++) { var p:Point = getPosition(i); items[i].x = size * p.x; items[i].y = size * p.y; } } private function getPosition(id:int):Point { if (id < 4) { return new Point(id, 0); }else if (id < 5) { return new Point(3, id - 3); }else if (id < 9) { return new Point(8 - id, 2); }else { return new Point(0, 1); } } } ![]() |
![]() |
![]() |
Часовой пояс GMT +4, время: 00:19. |
|
|
« Предыдущая тема | Следующая тема » |
|
|