Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 24.02.2013, 18:51
Жень Шень вне форума Посмотреть профиль Отправить личное сообщение для Жень Шень Найти все сообщения от Жень Шень
  № 1  
Ответить с цитированием
Жень Шень
 
Аватар для Жень Шень

блогер
Регистрация: Feb 2004
Адрес: Украина
Сообщений: 1,180
Записей в блоге: 3
Отправить сообщение для Жень Шень с помощью ICQ
По умолчанию Как перемещать объекты по периметру прямоугольника

Добрый день.
Пожалуйста, помогите советом или кодом. Есть объекты (для простоты квадратики) со свойствами 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};
Объекты (квадраты) располагаются строго в сетке и по периметру некого прямоугольника.
Как мне переместить объекты в соответствии с прилагаемым рисунком? Как бы провернуть по часовой стрелке по методу (функции).
Свой код не привожу, так как все равно не рабочий. А суть сводил к тому, что пытался получить массив новых индексов и присвоить объектам координаты прежних кубиков. Так как размер фигуры из квадратиков может быть произвольный, то универсальность не получалась. Буду рад любому совету. Спасибо.
Изображения
 

Старый 24.02.2013, 19:30
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 2  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
несколько раз прочитал, так и не понял что нужно сделать )

Старый 24.02.2013, 19:48
alatar вне форума Посмотреть профиль Отправить личное сообщение для alatar Найти все сообщения от alatar
  № 3  
Ответить с цитированием
alatar
 
Аватар для alatar

блогер
Регистрация: Dec 2008
Адрес: Israel, Natanya
Сообщений: 4,740
Записей в блоге: 11
Как-то так:
Код AS3:
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++;
        }
    } 
}
items — массив с вашими квадратиками.
offset — смещение первого элемента.

P.S. алгоритм писался сразу в браузере и не проверялся.
__________________
משיח לא בא
משיח גם לא מטלפן

Старый 24.02.2013, 20:33
Жень Шень вне форума Посмотреть профиль Отправить личное сообщение для Жень Шень Найти все сообщения от Жень Шень
  № 4  
Ответить с цитированием
Жень Шень
 
Аватар для Жень Шень

блогер
Регистрация: Feb 2004
Адрес: Украина
Сообщений: 1,180
Записей в блоге: 3
Отправить сообщение для Жень Шень с помощью ICQ
Цитата:
Сообщение от alatar Посмотреть сообщение
Как-то так
Спасибо, идею понял (результат на пикче), попробую подправить.

2:caseyryan. Приведенный в стартопике рисунок красноречивее описания: по часовой стрелке поменять клипы (квадраты в моем случае). Нулевой переходит на место первого, первый на место второго ... ну и так до последнего.
Изображения
 

Старый 24.02.2013, 20:38
alatar вне форума Посмотреть профиль Отправить личное сообщение для alatar Найти все сообщения от alatar
  № 5  
Ответить с цитированием
alatar
 
Аватар для alatar

блогер
Регистрация: Dec 2008
Адрес: Israel, Natanya
Сообщений: 4,740
Записей в блоге: 11
Надо поменять местами rows и cols в циклах и проверке.
__________________
משיח לא בא
משיח גם לא מטלפן

Старый 24.02.2013, 21:11
Жень Шень вне форума Посмотреть профиль Отправить личное сообщение для Жень Шень Найти все сообщения от Жень Шень
  № 6  
Ответить с цитированием
Жень Шень
 
Аватар для Жень Шень

блогер
Регистрация: Feb 2004
Адрес: Украина
Сообщений: 1,180
Записей в блоге: 3
Отправить сообщение для Жень Шень с помощью ICQ
Менял. Порядок в цепочке все равно меняется. Но пример натолкнул на вроде правильный алгортим. Сейчас пишу. Получится - выложу. Алгоритм следующий:
1. Беру нулевой элемент массива и смещаю вправо.
2. Затем следующий в массиве.Если вышел за предел возвращаю на место и смещаю вниз. Работаю со следующим.
3. Если опустился ниже нужного возвращаю и смещаю влево. Работаю со следующим.
4. Вышел за ноль возвращаю назад и поднимаю вверх. Работаю со следующим.
5. Вышел за ноль возвращаю на место. Финиш.
Вложения
Тип файла: rar rowcol.rar (5.7 Кб, 17 просмотров)

Старый 25.02.2013, 16:07
alatar вне форума Посмотреть профиль Отправить личное сообщение для alatar Найти все сообщения от alatar
  № 7  
Ответить с цитированием
alatar
 
Аватар для alatar

блогер
Регистрация: Dec 2008
Адрес: Israel, Natanya
Сообщений: 4,740
Записей в блоге: 11
Можно смещать элементы интерполяцией.
Код AS3:
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();
		}
	}
}
Rect.swf   (1.7 Кб)
Вложения
Тип файла: swf Rect.swf (1.7 Кб, 90 просмотров)
__________________
משיח לא בא
משיח גם לא מטלפן


Последний раз редактировалось alatar; 25.02.2013 в 16:22.
Старый 25.02.2013, 20:29
Жень Шень вне форума Посмотреть профиль Отправить личное сообщение для Жень Шень Найти все сообщения от Жень Шень
  № 8  
Ответить с цитированием
Жень Шень
 
Аватар для Жень Шень

блогер
Регистрация: Feb 2004
Адрес: Украина
Сообщений: 1,180
Записей в блоге: 3
Отправить сообщение для Жень Шень с помощью ICQ
Привет alatar! Классное решение.
А я выкрутился так:
- Зная длину массива, количество колонок и строк поделил объекты на 4 группы.
- 1-ю сдвигал вправо на шаг.
- 2-ю вниз.
= 3-ю влево.
- 4-ю - вверх.
Код AS3:
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]);
}
Изображения
 
Вложения
Тип файла: rar rowcol2.rar (12.5 Кб, 20 просмотров)

Старый 25.02.2013, 20:59
silin вне форума Посмотреть профиль Посетить домашнюю страницу silin Найти все сообщения от silin
  № 9  
Ответить с цитированием
silin
 
Аватар для silin

блогер
Регистрация: Mar 2003
Адрес: Моск. обл.
Сообщений: 5,269
Записей в блоге: 6
а вот может совсем по-простому
двигаем элементы в массиве по кольцу, а координаты определяем из текущего индекса
для конкретного прямоугольника 4х3
Код AS3:
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);
		}
	}
}
хотя да, если начать определять универсальные правила для координат что-то похожее на приведенное выше и получится

Старый 25.02.2013, 21:06
alatar вне форума Посмотреть профиль Отправить личное сообщение для alatar Найти все сообщения от alatar
  № 10  
Ответить с цитированием
alatar
 
Аватар для alatar

блогер
Регистрация: Dec 2008
Адрес: Israel, Natanya
Сообщений: 4,740
Записей в блоге: 11
Ну, мой алгоритм может работать с любыми многоугольниками.
__________________
משיח לא בא
משיח גם לא מטלפן

Создать новую тему Ответ Часовой пояс GMT +4, время: 00:19.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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