|
|
|||||
Регистрация: Jul 2012
Сообщений: 31
|
Линии и MouseEvent. Нужна помощь
Уважаемые флешеры, помогите пожалуйста в реализации вот такой вот вещи.
Есть сетка AxB, координаты пересечений линий выводил с помощью trace, то есть они есть. Нужно что бы можно было кликами создавать линии как показано на скриншоте. Линии должны накладываться только поверх линий сетки, длина - максимум до соседнего пересечения. Возможно ли такое? Если да, то как такое реализовать. Заранее благодарю. [IMG]http://s2.************/uploads/20120822/R2SgLVUm.png[/IMG] Последний раз редактировалось Snopka; 22.08.2012 в 22:17. |
|
|||||
Кликами? В смысле рисовать мышкой линии от координат x1,y1 до координат x2,y2?
|
|
|||||
Регистрация: Jul 2012
Сообщений: 31
|
Да, именно так
|
|
|||||
Так это же просто. При одном клике взять координаты мыши, при втором взять вторые и нарисовать линию с ними.
|
|
|||||
Регистрация: Jul 2012
Сообщений: 31
|
Это понятно, но нужно что бы координаты были равны координатам пересечений, что бы линии были четко на линиях сетки.
|
|
|||||
По моему вариант делать проверку, к каким точкам был клик ближе, и присваивать координаты точек. Правда не знаю, насколько сложно будет делать проверку только с ближайшими точками, а не "кликнул слева вверху и справа снизу и через всю сетку диагональ, зато две точки взяты из сетки".
|
|
|||||
Регистрация: Jul 2012
Сообщений: 31
|
Сделаю наверное невидимые кнопки на сетке
|
|
|||||
Регистрация: Mar 2012
Адрес: г.Новосибирск
Сообщений: 381
|
можно сделать допустим каждую линию классом, которая будет при нажатии менять свой цвет, и циклом их расставить по картинке
|
|
|||||
Можно как-то вот так. [см ниже]
Не спорю с тем, что можно сделать проще (наверное) и оптимальнее (точно) , но для примера вполне пойдет: P.S. Только что понял, что не очень-то понял задачу. Тов. Snopka, объясните подробнее, как себя должны вести линии при различных условиях. И как вообще строиться. 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) } } } 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); } } } } Результат примерно такой:
__________________
9 из 10 голосов в моей голове сказали наркотикам "НЕТ" Мои ачивки: художник-паразит. Последний раз редактировалось ChuwY; 23.08.2012 в 14:52. |
Часовой пояс GMT +4, время: 04:44. |
|
« Предыдущая тема | Следующая тема » |
Теги |
line , MouseEvent , линии |
|
|