![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
Регистрация: Apr 2016
Сообщений: 1
|
Доброе время суток. Я не давно начал осваивать программирование на флеш (as3) и столкнулся с такой проблемой как подключение готовых библиотек(классов)
Суть в том что есть игра с персонажем который должен ходить по динамической карте в точку нажатие мыши. С ходьбой проблем не возникло. А вот с поиском кратчайшего пути и обхода препятствий я решил использовать готовый варианты из интернета. То что искал я нашёл вот только как их теперь интегрировать в проект и как это вообще должно интегрироваться понятие не имею. Искал в гугле он видимо это так очевидно что об этом не чего полезного не нашёл. Решился попросить помощи у вас. Собственно сам пакет: package physics { import flash.display.MovieClip; import flash.display.Sprite; import flash.geom.Point; import flash.text.TextField; import flash.utils.Timer; import flash.events.TimerEvent; /** * Траектория движения. * Алгоритм поиска пути и обхождения препятствий. * * Ljuros.com * @author Romanson */ public class MoveTrajectory extends Sprite { public var pathFinded :Boolean = false; private var startPoint :Point; private var endPoint :Point; private var step :Number; private var walls :Array = new Array(); private var wallOffset :Number; public var path :Array;//Финальныпе контрольные точки траектории движения public var pathLength :Number = 0;//Длина пути private var usedPoints :Vector.<Point> = new Vector.<Point>(); private var usedPointsString:Vector.<String> = new Vector.<String>(); public var unit :Sprite; private var pathline :Sprite; private var rings :Sprite; public function MoveTrajectory(_startPoint:Point, _endPoint:Point, _unitRotat:Number, _actualBounds:Array, _step:Number = 10, _wallOffset:Number = 0) { unit = new Sprite(); walls = _actualBounds; startPoint = _startPoint; endPoint = _endPoint; step = _step; wallOffset = _wallOffset; //rings = new Sprite(); //addChild(rings); drawWalls(); //setRing(endPoint, 0x000000); //trace(endPointFree()); if(endPointFree()) checkNextPoint(startPoint); } //Проверить находится ли точка назначения внеобъектов (преград) private function endPointFree():Boolean { for each(var w:Array in walls) { var s1:Number = triangleVolume(w[0], w[1], endPoint); var s2:Number = triangleVolume(w[1], w[2], endPoint); var s3:Number = triangleVolume(w[2], w[3], endPoint); var s4:Number = triangleVolume(w[3], w[0], endPoint); var s:Number = lineLength(w[0], w[1]) * lineLength(w[1], w[2]); if ( Math.round(s) == Math.round(s1+s2+s3+s4) ) { return false; } } return true } private function triangleVolume(p1:Point, p2:Point, p3:Point):Number { var a:Number = lineLength(p1, p2); var b:Number = lineLength(p2, p3); var c:Number = lineLength(p3, p1); var p:Number = (a + b + c) / 2; return Math.sqrt(p * (p - a) * (p - B) * (p - c)); } //Проверка следующей точки (шага) private function checkNextPoint(p:Point, refind:Boolean = false):void { var n:Point = new Point(p.x, p.y - step); var e:Point = new Point(p.x + step, p.y); var s:Point = new Point(p.x, p.y + step); var w:Point = new Point(p.x - step, p.y); var ne:Point = new Point(p.x + step, p.y - step); var se:Point = new Point(p.x + step, p.y + step); var nw:Point = new Point(p.x - step, p.y - step); var sw:Point = new Point(p.x - step, p.y + step); var points:Array = pointToCheck(n, e, s, w, ne, se, nw, sw); var closestPoint:Point; for (var ii:int = 0; ii < points.length; ii++){ if (!isWallCollision(p, points[ii])) { closestPoint = points[ii]; break; } } if (closestPoint != null) { if(points.length>1){ for (var i:int = 1; i < points.length; i++){ if (lineLength(endPoint, closestPoint) > lineLength(endPoint, points[i]) && !isWallCollision(p, points[i])){ closestPoint = points[i]; } } } usedPoints.push(p); usedPointsString.push(p.toString()); //setRing(closestPoint, 0xff7711); //Конечная точка найдена if (lineLength(endPoint, closestPoint) < 20 || !isWallCollision(endPoint, p)) findClosestPath(); else checkNextPoint(closestPoint); }else { usedPoints.push(p); usedPointsString.push(p.toString()); //Скрипт заблокировал точку сам в себе, поиск новой точки отсчёта findNextStartPoint(); } } //Поиск новой точки для продолжения поиска private function findNextStartPoint():void { //trace(" FIND NEW START POINT ------------------------------"); var freePoints:Array = new Array(); for each(var p:Point in usedPoints) { var n:Point = new Point(p.x, p.y - step); var e:Point = new Point(p.x + step, p.y); var s:Point = new Point(p.x, p.y + step); var w:Point = new Point(p.x - step, p.y); var ne:Point = new Point(p.x + step, p.y - step); var se:Point = new Point(p.x + step, p.y + step); var nw:Point = new Point(p.x - step, p.y - step); var sw:Point = new Point(p.x - step, p.y + step); var points:Array = pointToCheck(n, e, s, w, ne, se, nw, sw); if (points.length > 0) { for (var i:int = 0; i < points.length; i++){ if (!isWallCollision(p, points[i])) { freePoints.push(points[i]); } } } } var closestPoint:Point = freePoints[0]; for (var i2:int = 1; i2 < freePoints.length; i2++) { if (lineLength(endPoint, closestPoint) > lineLength(endPoint, freePoints[i2])){ closestPoint = freePoints[i2]; } } //setRing(closestPoint, 0xde55de); checkNextPoint(closestPoint, true); } private function playback():void { var timer:Timer = new Timer(70, 1); timer.addEventListener(TimerEvent.TIMER_COMPLETE, function():void { rings.removeChildAt(0); if (rings.numChildren > 1) playback(); } ); timer.start(); } private function pointToCheck(n:Point, e:Point, s:Point, w:Point, ne:Point, se:Point, nw:Point, sw:Point):Array { var arr:Array = new Array(); if (usedPointsString.indexOf(n.toString()) == -1) arr.push(n); if (usedPointsString.indexOf(e.toString()) == -1) arr.push(e); if (usedPointsString.indexOf(s.toString()) == -1) arr.push(s); if (usedPointsString.indexOf(w.toString()) == -1) arr.push(w); if (usedPointsString.indexOf(ne.toString()) == -1) arr.push(ne); if (usedPointsString.indexOf(se.toString()) == -1) arr.push(se); if (usedPointsString.indexOf(nw.toString()) == -1) arr.push(nw); if (usedPointsString.indexOf(sw.toString()) == -1) arr.push(sw); return arr; } //Проверка на столкновение с преградой private function isWallCollision(sp:Point, ep:Point):Boolean { for each(var wall:Array in walls) { for (var i:int = 0; i < wall.length; i++ ) { var i2:int = i == wall.length - 1 ? 0 : i + 1; var p:Point = linesCross(wall[i], wall[i2], sp, ep); if (p != null) { return true; } } } return false; } //Точка пересечения двух отрезков private function linesCross(p1:Point, p2:Point, p3:Point, p4:Point):Point { var ua:Number = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / ( (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y) ); var ub:Number = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / ( (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y) ); //Узнать есть ли точка пересечения if ( (0 <= ua && ua <= 1) && (0 <= ub && ub <= 1) ) { //Координаты точки пересечения var xy:Point = new Point(p1.x + ua * (p2.x - p1.x), p1.y + ua * (p2.y - p1.y)); //setRing(xy, 0xff00cc); return xy; } return null; } //Длина прямой private function lineLength(p1:Point, p2:Point):Number { return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)); } //Рассчёт оптимального пути от начальной до конечной точки private function findClosestPath():void { path = new Array(); path.push(endPoint); usedPoints.reverse(); usedPoints.push(startPoint); var lastVisiblePoint:Point = endPoint; var p:Point; for (var i:int = 1; i < usedPoints.length; i++ ) { p = usedPoints[i]; //Если нет преграды между текущей точкой и конечной if (!isWallCollision(startPoint, p)) { lastVisiblePoint = usedPoints[i]; path.push(lastVisiblePoint); break; } //Если есть преграда между последней контрольноый точкой и текущей if (isWallCollision(lastVisiblePoint, p)) { lastVisiblePoint = usedPoints[i - 1]; path.push(lastVisiblePoint); } } //Полный путь от начальной точки path.push(startPoint); path.reverse(); //Длина пути (для вычисления скорости / времени проходжения) for (var l:int = 0; l < path.length-1; l++) { pathLength += lineLength(path[l], path[l+1]); } //Удалить начальныю точку, т.к. персонаж уже на ней path.shift(); unit.x = startPoint.x; unit.y = startPoint.y; //addChild(unit); pathFinded = true; } // --------------------------------------------------- private function drawWalls():void { for each(var wall:Array in walls) { var w:Sprite = new Sprite(); w.graphics.lineStyle(1, 0x35d4f8); w.graphics.moveTo(wall[0].x, wall[0].y); w.graphics.lineTo(wall[1].x, wall[1].y); w.graphics.lineTo(wall[2].x, wall[2].y); w.graphics.lineTo(wall[3].x, wall[3].y); w.graphics.lineTo(wall[0].x, wall[0].y); addChild(w); } } private function setRing(p:Point, c:uint):void { var s:Sprite = new Sprite(); s.graphics.beginFill©; s.graphics.drawCircle(0, 0, 3); s.x = p.x; s.y = p.y; addChild(s); } } } Буду очень благодарен за помощь. Последний раз редактировалось Wolsh; 04.04.2016 в 13:35. |
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Для оформления своего кода используйте теги AS3.
Добавлено через 4 минуты это что, скан? Цитата:
__________________
Reality.getBounds(this); |
|
|||||
|
Советую почитать про A* (A-Star) как про самый распространенный алгоритм. Есть даже готовые имплементации на AS3.
А на счет этого кода, как-то нет желания ковыряться в этой каше
__________________
Ко мне можно и нужно обращаться на ты) |
![]() |
![]() |
Часовой пояс GMT +4, время: 08:51. |
|
|
« Предыдущая тема | Следующая тема » |
|
|