建议在新窗口中查看:
http://www.dotnet.pp.ru/silverlight/SilverlightAStar.html

花了几天的时间研究A*算法,总算是搞出来了。放上来给大伙儿瞧瞧。
点击“StartPoint”指定开始点,点击“EndPoint”指定目标点。点击“Impediment”指定不可通过区域。
GridSize设置节点大小,节点越小,容器中的节点就越多,填好后点Set保存设置。
Clear清除所有。
StartFindPath 开始寻径
Completed Tim 显示寻径所耗时间。
Diagonals 设置是否可以斜着走。
自我感觉速度不错。
下面说说算法的大致流程
首先定义两个列表
private List<PathNote> openedList = new List<PathNote>(); //开启列表
private List<PathNote> colsedList = new List<PathNote>(); //关闭列表
开启列表中存储待检测节点。关闭列表中存储已检测节点。
从开始点开始,拿到开始点周围4或8个方向的节点,把他们添加进开启列表中。
G等于当前节点的父节点加上10或者14,水平或垂直方向加10,对角线方向加14
H等于当前节点的X的差与目标的的X的差、Y与目标点Y的差的绝对值的和。
F = G + H。
把当前节点从开启列表中删除。并添加进关闭列表中。以“F”值为依据从小到大排序,把F值最小的节点拿出来,重复以上过程。
大致流程是这样的。细节方面已经有一篇文章写的非常详细,在此也没有必要赘述了。
传送门:http://data.gameres.com/message.asp?TopicID=25439
最后放上算法的代码,不多。直接以文本形式发出来算了。
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
namespace SilverlightAStar
{
public class PathNote
{
public int F; //F = G + H
public int G;
public int H;
public int X;
public int Y;
public PathNote parentNote;
}
public class PathFinder
{
/// <summary>
/// 矩阵
/// </summary>
private byte[,] matrix;
/// <summary>
/// 开始点
/// </summary>
private Point startPoint;
/// <summary>
/// 结束点
/// </summary>
private Point endPoint;
/// <summary>
/// 开启列表
/// </summary>
private List<PathNote> openedList = new List<PathNote>(); //开启列表
/// <summary>
/// 关闭列表
/// </summary>
private List<PathNote> colsedList = new List<PathNote>(); //关闭列表
/// <summary>
/// 是否允许斜线行走
/// </summary>
private bool diagonals;
/// <summary>
/// 方向
/// </summary>
private sbyte[,] direction = new sbyte[8, 2] { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 }, { 1, -1 }, { 1, 1 }, { -1, 1 }, { -1, -1 } }; //默认方向
/// <summary>
/// 构造函数
/// </summary>
/// <param name="matrix">待检测矩阵</param>
/// <param name="startPoint">开始点</param>
/// <param name="endPoint">结束点</param>
public PathFinder(byte[,] matrix, Point startPoint, Point endPoint)
{
this.matrix = matrix;
this.startPoint = startPoint;
this.endPoint = endPoint;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="matrix">矩阵</param>
/// <param name="startPoint">开始点</param>
/// <param name="endPoint">结束点</param>
/// <param name="diagonals">是否允许斜线行走</param>
public PathFinder(byte[,] matrix, Point startPoint, Point endPoint, bool diagonals)
{
this.matrix = matrix;
this.startPoint = startPoint;
this.endPoint = endPoint;
this.diagonals = diagonals;
if (!diagonals)
{
direction = new sbyte[4, 2] { { 0, -1 }, { 0, 1 }, { -1, 0 }, { 1, 0 } }; //不允许穿角,4方向
}
}
/// <summary>
/// 开始寻找路径
/// </summary>
/// <returns></returns>
public List<Point> StartFindPath()
{
var found = false;
var pathNote = new PathNote() { F = 0, G = 0, H = 0, X = (int)startPoint.X, Y = (int)startPoint.Y, parentNote = null };
List<Point> resultPoints = null;
while (true)
{
for (int i = 0; i < (diagonals ? 8 : 4); i++) //找到pathNote四方向或八方向周围节点,取F值最小的那个继续此过程
{
var x = pathNote.X + direction[i, 0];
var y = pathNote.Y + direction[i, 1];
if (x < 0 || y < 0 || x > matrix.GetUpperBound(0) || y > matrix.GetUpperBound(1)) //坐标过界
continue;
var newPathNote = new PathNote();
newPathNote.parentNote = pathNote;
newPathNote.X = x;
newPathNote.Y = y;
bool isClosed = false;
bool isOpened = false;
PathNote theOpendandSameNote = null;
foreach (var closedNote in colsedList)
{
if (closedNote.X == newPathNote.X && closedNote.Y == newPathNote.Y)
{
isClosed = true; //节点已经在关闭列表中
}
}
foreach (var openedNote in openedList)
{
if (openedNote.X == newPathNote.X && openedNote.Y == newPathNote.Y)
{
isOpened = true; //节点已经在开启列表中,稍后比较两条路径
theOpendandSameNote = openedNote;
}
}
if (matrix[newPathNote.X, newPathNote.Y] != 0 || isClosed) //不能通行或者已经在关闭列表中存在
continue;
if (Math.Abs(direction[i, 0] + direction[i, 1]) == 2) //G值
{
newPathNote.G = newPathNote.parentNote.G + 14;
}
else
{
newPathNote.G = newPathNote.parentNote.G + 10;
}
newPathNote.H = (int)(Math.Abs(endPoint.X - newPathNote.X) + Math.Abs(endPoint.Y - newPathNote.Y)) * 10; //H值
newPathNote.F = newPathNote.G + newPathNote.H; //F值
if (isOpened) //比较已在开启列表中的节点G值和准备创建的节点G值
{
if (newPathNote.G >= theOpendandSameNote.G)
{
this.openedList.Remove(pathNote);
continue;
}
else
{
this.openedList.Remove(theOpendandSameNote);
this.openedList.Add(newPathNote);
continue;
}
}
this.openedList.Add(newPathNote); //创建节点(添加进开启列表)
}
this.colsedList.Add(pathNote); //把当前节点放进关闭列表
this.openedList.Remove(pathNote); //从开启列表移除当前节点
foreach (var openedNote in openedList)
{
if (openedNote.X == (int)endPoint.X && openedNote.Y == (int)endPoint.Y) // 到达终点
{
resultPoints = GetPointListByParent(openedNote, null); //得到以Point构成的路径
found = true;
break;
}
}
if (found)
{
break;
}
else
{
if (openedList.Count == 0) //找不到路径
{
break;
}
else
{
openedList.Sort(Compare);
pathNote = openedList[0];
}
}
}
return resultPoints;
}
/// <summary>
/// 组织传入的PathNote的所有父节点为List
/// </summary>
/// <param name="pathNote">PathNote</param>
/// <param name="pathPoints">列表</param>
/// <returns>路径</returns>
private List<Point> GetPointListByParent(PathNote pathNote, List<Point> pathPoints)
{
if (pathPoints == null)
pathPoints = new List<Point>();
if (pathNote.parentNote != null)
{
pathPoints.Add(new Point(pathNote.parentNote.X, pathNote.parentNote.Y));
GetPointListByParent(pathNote.parentNote, pathPoints);
}
return pathPoints;
}
/// <summary>
/// 比较两个节点的F值
/// </summary>
/// <param name="x">第一个节点</param>
/// <param name="y">第二个节点</param>
/// <returns></returns>
private int Compare(PathNote x, PathNote y)
{
if (x.F > y.F)
return 1;
else if (x.F < y.F)
return -1;
return 0;
}
}
}
文章出处:http://www.cnblogs.com/zhubenwuzui/archive/2009/09/18/1569534.html 猪笨无罪的博客
分享到:
相关推荐
本资源“共享Silverlight版A*路径寻径算法包”提供了在Silverlight环境中实现A*(A-Star)算法的解决方案。A*算法是一种广泛应用的启发式搜索算法,以其高效性和准确性著称,它在寻找两点间的最短路径时,结合了...
总的来说,A*寻路算法在Silverlight中的实现是一个集成了算法理论与实践操作的案例,对学习者来说具有很高的参考价值,可以帮助他们掌握路径规划的基本原理,并能将其应用到各种实际问题中,如迷宫求解、游戏AI路径...
将 **Silverlight 4** 与 **SharePoint 2010** 结合使用,可以显著增强企业应用的功能性和用户体验,实现更高级的数据可视化、用户界面设计及更复杂的应用逻辑。 #### 二、Silverlight 4 和 SharePoint 2010 的集成...
- **什么是Silverlight**:Silverlight是一种浏览器插件,它可以增强网页的媒体播放、图形展示和用户交互功能。 - **目标平台**:Silverlight支持多种操作系统和浏览器,包括Windows、Mac OS以及主流的Web浏览器。 -...
在Silverlight中实现A星算法,通常涉及到以下几个步骤: 1. **建立网格**:将地图划分为可行走的格子,每个格子代表一个节点,记录其邻居节点。 2. **定义代价函数**:确定每移动一格的成本,如平坦地面与障碍物的...
接着,教程⑦介绍了A*寻径算法,这是一种高效的路径规划方法,用于解决游戏中的智能体如何在复杂环境中找到最优路径的问题。 第⑧和⑨章则深入到A*寻径算法的动态应用,展示了如何将寻径结果实时转化为动画效果,使...
**Silverlight技术详解** Silverlight是由微软开发的一种插件技术,用于在Web浏览器中呈现丰富的媒体和交互式应用程序。这项技术在2007年首次发布,旨在与Adobe的Flash平台竞争,提供跨平台、跨浏览器的多媒体和...
5. **数据访问**:介绍如何在Silverlight应用中实现数据绑定,使用ADO.NET Entity Framework或其他数据访问技术来与数据库交互。 6. **Silverlight控件**:详述Silverlight提供的各种内置控件,如按钮、文本框、...
Silverlight在2007年首次发布,目的是与Adobe Flash竞争,提供一种跨浏览器、跨平台的插件来实现高质量的多媒体播放和交互性应用。虽然Silverlight在早期受到了一定的关注,但随着HTML5的兴起和微软的策略调整,...
在深入研究这些源码时,我们可以学习到如何设计和实现Silverlight应用,以及如何利用其特性提升Web应用的交互性和性能。通过对这些源码的解构和学习,开发者能够更好地理解和运用Silverlight技术,为自己的项目增添...
**Microsoft Silverlight** 是一种由微软公司开发的跨浏览器、跨平台的插件,主要用于增强Web应用程序的多媒体体验。它在2007年首次发布,版本为1.0,标志着微软进入富互联网应用程序(RIA)领域的尝试,与Adobe ...
- **OData支持**:Silverlight可以利用OData协议与Web服务进行数据交换,实现前后端的交互。 - **离线应用**:通过结合Silverlight Out-of-Browser(OOB)功能,可以创建能在本地运行的离线应用程序。 通过深入...
【标题】"Silverlight实现的多图片列表框"是一个基于微软的Silverlight技术构建的应用示例,它展示了如何在Silverlight应用中展示多个图片,并以列表框的形式进行展示。这个项目可能是一个用户界面组件,用于在Web...
4. **深度集成数据绑定**:Silverlight 3增强了数据绑定机制,使开发者能更容易地将数据与UI元素关联,实现数据驱动的用户界面。 5. **强大的文本渲染**:引入了新的文本引擎,提供了更好的字体渲染和文本排版,...
首先,我们来了解一下**Silverlight**。Silverlight是微软推出的一种RIA(Rich Internet Application)技术,它提供了一种创建具有丰富媒体体验和交互式用户界面的Web应用程序的方式。通过XAML(Extensible ...
源代码中包含的“silverlight寻光之旅”很可能涵盖上述各个知识点的具体实现,通过阅读和分析这些代码,开发者能够深入理解Silverlight的各种特性和应用场景,并从中学习如何构建高效、互动的Web应用。
**Silverlight介绍** Silverlight是由微软开发的一种富互联网应用程序(RIA)平台,它主要用于构建和展示具有丰富媒体体验和交互式用户界面的Web应用。Silverlight支持多媒体、动画、图形和交互式功能,广泛应用于...
**Silverlight** 是微软推出的一种跨浏览器的富互联网应用程序(RIA)框架,旨在为 Web 开发者提供一个强大的平台来创建具有高度交互性的用户界面。自2007年9月首次发布以来,Silverlight 不断发展和完善,为开发者...
- **数据绑定和数据服务**:Silverlight支持WCF(Windows Communication Foundation)服务,可以方便地与Web服务进行交互,实现数据的获取和提交。 - **AJAX集成**:可以与现有的ASP.NET AJAX应用程序集成,提供更...