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

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

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему  
Старый 23.08.2012, 13:13
ChuwY вне форума Посмотреть профиль Отправить личное сообщение для ChuwY Посетить домашнюю страницу ChuwY Найти все сообщения от ChuwY
  № 10  
Ответить с цитированием
ChuwY
 
Аватар для ChuwY

Регистрация: Nov 2009
Адрес: Тула / Москва
Сообщений: 734
Отправить сообщение для ChuwY с помощью ICQ Отправить сообщение для ChuwY с помощью Skype™
Можно как-то вот так. [см ниже]
Не спорю с тем, что можно сделать проще (наверное) и оптимальнее (точно) , но для примера вполне пойдет:

P.S. Только что понял, что не очень-то понял задачу.
Тов. Snopka, объясните подробнее, как себя должны вести линии при различных условиях. И как вообще строиться.

Код:
LineSegment.as
Код AS3:
package gridExample.grid
{
	import flash.geom.Point;
 
	/**
	 * Класс модели отрезка.
	 * Координаты конца и начала -- координаты сетки, а не дисплейные
	 * @author chu
	 */
	public class LineSegment
	{
		private var _start : Point;
		private var _end : Point;
		private var _color : uint;
		public function LineSegment(start : Point, end : Point, color : uint = 0x0)
		{
			_start = start;
			_end = end;
			_color = color;
		}
 
		//***  public ***//
		public function get start():Point
		{
			return _start;
		}
 
		public function get end():Point
		{
			return _end;
		}
 
		public function get color():uint
		{
			return _color;
		}
 
		public function set color(value : uint):void
		{
			_color = value;
		}
 
		public function hasCoincidence(start : Point, end : Point):Boolean
		{
			return hasDirectCoincidence(start, end) || hasDirectCoincidence(end, start);
		}
 
		//*** private ***//
		private function hasDirectCoincidence(start : Point, end : Point):Boolean
		{
			return this.start.equals(start) && this.end.equals(end)
		}
	}
}

Код:
Grid.as
Код AS3:
package gridExample.grid
{
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.geom.Point;
 
	public class Grid extends Sprite
	{
		private static const CELL_SIZE : uint = 70;
		private static const BG_FILL_COLOR : uint = 0xAAAAAA;
		private static const BG_LINES_COLOR : uint = 0x555555;
		private static const BG_LINES_THICKNESS : Number = 2;
		private static const BG_BORDER_THICKNESS : Number = 6;
		private static const CELL_COLOR : uint = 0xFFFFFF;
		private static const SEGMENTS_LINE_THICKNESS : uint = 4;
		private static const COLLISED_PREVIEW_ALPHA : Number = 0.5;
		private static const DEFAULT_ALPHA : Number = 1;
		// model
		private var _rows : uint;
		private var _cols : uint;
		private var _currentColor : uint;
		private var _allowReplacing : Boolean;
		private var _segments : Vector.<LineSegment> = new Vector.<LineSegment>();
		private var _currentSegment : LineSegment;
		// subview
		private var _bg : Shape;
		private var _linesContainer : Shape;
		public function Grid()
		{
			getControls();
		}
 
		//*** public ***//
		public function clearLines():void
		{
			_segments.splice(0, _segments.length);
			_linesContainer.graphics.clear();
		}
 
		public function setSize(cols : uint, rows : uint):void
		{
			_rows = rows;
			_cols = cols;
			drawBg();
			drawSegments();
		}
 
		public function setCurrentColor(color : uint):void
		{
			_currentColor = color;
		}
 
		public function setAllowReplacing(value : Boolean):void
		{
			_allowReplacing = value;
		}
 
		public function buildLine(x : Number, y : Number, preview : Boolean = false):void
		{
			var col : int = Math.floor(x/CELL_SIZE);
			var row : int = Math.floor(y/CELL_SIZE);
			var segment : LineSegment;
 
			if(hasOutside(col, row))
			{
				return;
			}
 
			segment = getNearestSegment(x, y);
			handleNewSegment(segment, preview);
 
			drawSegments();
		}
 
		//*** private ***//
		private function hasSlotBused(segment : LineSegment):Boolean
		{
			var oldSegment : LineSegment = getSegmentByPosition(segment.start, segment.end);
			return oldSegment != null;
		}
 
		private function handleNewSegment(segment : LineSegment, preview : Boolean):void
		{
			var isBusy : Boolean = hasSlotBused(segment);
 
			if(preview || (isBusy && !_allowReplacing))
			{
				_currentSegment = segment;
				return;
			}
 
			if(isBusy && _allowReplacing)
			{
				getSegmentByPosition(segment.start, segment.end, true);
			}
			_segments.push(segment);
		}
 
		private function getSegmentByPosition(start : Point, end : Point, remove : Boolean = false):LineSegment
		{
			var numSegments : uint = _segments.length;
			while(numSegments--)
			{
				var segment : LineSegment = _segments[numSegments];
				if(segment.hasCoincidence(start, end))
				{
					if(remove)
					{
						_segments.splice(numSegments, 1);
					}
					return segment;
				}
			}
			return null;
		}
 
		/**
		 * Возвращает вектор нормали от указанной точки до ближайшего отрезка
		 * пикселы
		 */
		private function getNormal(x : uint, y : uint):Point
		{
			var xLen : Number = x - Math.round(x/CELL_SIZE)*CELL_SIZE;
			var yLen : Number = y - Math.round(y/CELL_SIZE)*CELL_SIZE;
			var isVert : Boolean = Math.abs(yLen) < Math.abs(xLen);
			var dirX : Number = isVert ? 0 : xLen;
			var dirY : Number = isVert ? yLen : 0;
 
			return new Point(dirX, dirY);
		}
 
		private function getNearestSegment(x : uint, y : uint):LineSegment
		{
			var normal : Point = getNormal(x, y);
			var startX : uint; 
			var startY : uint; 
			var endX : uint;
			var endY : uint;
 
			if(normal.x)
			{
				startX = (x - normal.x)/CELL_SIZE;
				startY = Math.floor(y/CELL_SIZE);	
				endX = startX;
				endY = Math.ceil(y/CELL_SIZE);
			} 
			else
			{
				startX = Math.floor(x/CELL_SIZE);	
				startY = (y - normal.y)/CELL_SIZE;
				endX = Math.ceil(x/CELL_SIZE);
				endY = startY;
			}
 
			return new LineSegment(new Point(startX, startY), new Point(endX, endY), _currentColor);
		}
 
		private function getControls():void
		{
			_bg = new Shape();
			addChild(_bg);
 
			_linesContainer = new Shape();
			addChild(_linesContainer);
		}
 
		private function drawSegments():void
		{
			var graph : Graphics = _linesContainer.graphics;
 
			graph.clear();
 
			for each(var segmentParam : LineSegment in _segments)
			{
				drawSegment(segmentParam, graph);
			}
			if(_currentSegment)
			{
				var isCollision : Boolean = hasSlotBused(_currentSegment);
				var alpha : Number = isCollision ? COLLISED_PREVIEW_ALPHA : DEFAULT_ALPHA;
				drawSegment(_currentSegment, graph, alpha);
			}
		}
 
		private function drawSegment(segment : LineSegment, graph : Graphics, alpha : Number = DEFAULT_ALPHA):void
		{
			// ячейки
			var start : Point = segment.start;
			var end : Point = segment.end;
 
			//проверка на вхождение отрезка в зону отображения
			if(hasPointOutside(start) || hasPointOutside(end))
			{
				return;
			}
 
			// пикселы
			var startX : uint = start.x * CELL_SIZE;
			var startY : uint = start.y * CELL_SIZE;
			var endX : uint = end.x * CELL_SIZE;
			var endY : uint = end.y * CELL_SIZE;
 
			graph.lineStyle(SEGMENTS_LINE_THICKNESS, segment.color, alpha);
			graph.moveTo(startX, startY);
			graph.lineTo(endX, endY);
		}
 
		private function hasPointOutside(point : Point):Boolean
		{
			return hasOutside(point.x, point.y);
		}
 
		private function hasOutside(col : Number, row : Number):Boolean
		{
			return (col < 0) || (col > _cols) || (row < 0) || (row > _rows);
		}
 
		private function drawBg():void
		{
			var graph : Graphics = _bg.graphics;
			var width : uint = CELL_SIZE * _cols;
			var height : uint = CELL_SIZE * _rows;
 
			graph.clear();
 
			// бордюр и фон
			graph.beginFill(BG_FILL_COLOR);
			graph.lineStyle(BG_BORDER_THICKNESS, BG_LINES_COLOR);
			graph.drawRect(0, 0, width, height);
 
			// остальные линии
			graph.endFill();
			graph.lineStyle(BG_LINES_THICKNESS, BG_LINES_COLOR);
 
			for(var col : uint = 1; col < _cols; col++)
			{
				var currentX : uint = CELL_SIZE * col;
				graph.moveTo(currentX, 0);
				graph.lineTo(currentX, height);
			}
			for(var row : uint = 1; row < _rows; row++)
			{
				var currentY : uint = CELL_SIZE * row;
				graph.moveTo(0, currentY);
				graph.lineTo(width, currentY);
			}
		}
	}
}
Остальное в приложенных исходниках.
Результат примерно такой:
Миниатюры
Нажмите на изображение для увеличения
Название: gridExampleScreen2.jpg
Просмотров: 438
Размер:	57.5 Кб
ID:	28370  
Вложения
Тип файла: rar GridExample.rar (896.7 Кб, 525 просмотров)
__________________
9 из 10 голосов в моей голове сказали наркотикам "НЕТ"
Мои ачивки: художник-паразит.


Последний раз редактировалось ChuwY; 23.08.2012 в 14:52.
Создать новую тему   Часовой пояс GMT +4, время: 13:46.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Теги
line , MouseEvent , линии

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

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


 


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


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