Показать сообщение отдельно
Старый 04.04.2016, 13:13
proff007 вне форума Посмотреть профиль Отправить личное сообщение для proff007 Найти все сообщения от proff007
  № 1  
Ответить с цитированием
proff007

Регистрация: Apr 2016
Сообщений: 1
По умолчанию Подключение готовых библиотек поиска пути

Доброе время суток. Я не давно начал осваивать программирование на флеш (as3) и столкнулся с такой проблемой как подключение готовых библиотек(классов)
Суть в том что есть игра с персонажем который должен ходить по динамической карте в точку нажатие мыши. С ходьбой проблем не возникло. А вот с поиском кратчайшего пути и обхода препятствий я решил использовать готовый варианты из интернета. То что искал я нашёл вот только как их теперь интегрировать в проект и как это вообще должно интегрироваться понятие не имею. Искал в гугле он видимо это так очевидно что об этом не чего полезного не нашёл. Решился попросить помощи у вас.
Собственно сам пакет:
Код 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);
}
}
 
}
и источник http://ljuros.com/post/geometrija_al...a_prepjatstvij (мало ли)
Буду очень благодарен за помощь.


Последний раз редактировалось Wolsh; 04.04.2016 в 13:35.