上一段时间一直在阅读“深蓝色”的游戏制作教程,其中第十二讲提到了地图副本,即如下:(引自蓝色的博客)
代码下载地址,https://files.cnblogs.com/wangweixznu/WpfGameStudy.rar
具体详细内容讲解可以参考http://www.cnblogs.com/alamiye010/archive/2009/06/17/1505342.html
但是感觉有一个问题就是对于一旦用到A*算法就要涉及用二维矩阵来构建地图的障碍物,然而大家都知道,一款游戏的地图是很复杂的,障碍物也很复杂,如果纯粹靠编程的方式来精确定位障碍物难免有些麻烦,必须在在图像处理工具上标出每个障碍物的具体位置,然后在一一构建障碍物矩阵,利用深蓝色这篇文章中的道理,我想了一个方法,如果我们在加载地图的时候就能够自动创建障碍物矩阵,岂不是更好,那才是真正面向对象编程,地图由你怎么换,你只要给我提供一副黑白图片即可以了,加载地图的时候会根据黑白地图即地图副本自动创建障碍物矩阵
具体代码如下:页面代码
<Window x:Class="WpfGameStudy.AStarMapDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AStarMapDemo" Width="650" Height="650">
<Canvas Name="canvas" Width="600" Height="600" Background="Gray" MouseLeftButtonDown="canvas_MouseLeftButtonDown"></Canvas>
</Window>
对应后台代码:
using System;2
using System.Collections.Generic;3
using System.Linq;4
using System.Text;5
using System.Windows;6
using System.Windows.Controls;7
using System.Windows.Data;8
using System.Windows.Documents;9
using System.Windows.Input;10
using System.Windows.Media;11
using System.Windows.Media.Imaging;12
using System.Windows.Shapes;13
using System.Windows.Media.Animation;14
using System.IO;15

16
using QX.Game.PathFinder;17
namespace WpfGameStudy18
{19
/// <summary>20
/// 演示A*和自动构建地图路径算法21
/// </summary>22
public partial class AStarMapDemo : Window23
{ 24
Rectangle person; //模拟任务的方块25
byte[,] Matric = null;26
System.Drawing.Point stratPoint;//起始点坐标27
System.Drawing.Point endPoint;//终点坐标28
Image map = null;//地图29
ComboBox cboMap;//供选择的地图30
IPathFinder pathFinder;31
int gridSize = 20;32
public AStarMapDemo()33
{34
35
InitializeComponent();36
InitMap();37
}38
/// <summary>39
/// 初始化地图40
/// </summary>41
void InitMap()42
{43
//提供供用户选择的地图58
stratPoint = new System.Drawing.Point(1, 1);//模拟人物起始点59

60
Matric = PathGrid("CopyMap\\" + cboMap.SelectedItem.ToString(), gridSize);//生成障碍物路径61
map = new Image();62
map.Source = (ImageSource)(new CroppedBitmap(BitmapFrame.Create(new Uri("CopyMap\\" + cboMap.SelectedItem.ToString(), UriKind.Relative)), new Int32Rect(0, 0, 600, 600)));63
64
map.Width = 600;65
map.Height = 600;66
Canvas.SetTop(map,0);67
Canvas.SetLeft(map, 0);68
69
canvas.Children.Add(map);70
//创建人物,用一个红色小方块表示71
person = new Rectangle();72
person.Width = gridSize;73
person.Height = gridSize;74
person.Fill = new SolidColorBrush(Colors.Red);75
canvas.Children.Add(person);76
Canvas.SetTop(person, stratPoint.X * gridSize);77
Canvas.SetLeft(person, stratPoint.Y * gridSize);78

79
80
}81

82
void cboMap_SelectionChanged(object sender, SelectionChangedEventArgs e)83
{84
Matric = PathGrid("CopyMap\\" + cboMap.SelectedItem.ToString(), gridSize);//生成障碍物路径85
map.Source = (ImageSource)(new CroppedBitmap(BitmapFrame.Create(new Uri("CopyMap\\" + cboMap.SelectedItem.ToString(), UriKind.Relative)), new Int32Rect(0, 0, 600, 600)));86

87
//测试地图是否跟图像一样,不需要删掉99
}100

101
private void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)102
{103
stratPoint = new System.Drawing.Point((int)Canvas.GetLeft(person) / gridSize, (int)Canvas.GetTop(person) / gridSize);//记录先当前新起始点104

105
Point point = e.GetPosition(canvas);106
endPoint = new System.Drawing.Point((int)point.X / gridSize, (int)point.Y / gridSize);//记录当期终点107

108
pathFinder = new PathFinder(Matric);109
pathFinder.SearchLimit = 200000;110
pathFinder.Formula = HeuristicFormula.Manhattan;111
pathFinder.HeavyDiagonals = true;//对角线移动112
List<PathFinderNode> path = pathFinder.FindPath(stratPoint, endPoint);113

114
if (path == null)115
MessageBox.Show("没有路径通过");116
else117
{118
Point[] pathPoint = new Point[path.Count];119
for (int i = 0; i < path.Count; i++)120
{121
pathPoint[i] = new Point((int)path[i].X * gridSize, (int)path[i].Y * gridSize);122
}123
Storyboard action = new Storyboard();124
int time = 100;125
//创建X轴上动画126
DoubleAnimationUsingKeyFrames animX = new DoubleAnimationUsingKeyFrames();127
animX.Duration = TimeSpan.FromMilliseconds(path.Count * 100);128
Storyboard.SetTarget(animX, person);129
Storyboard.SetTargetProperty(animX, new PropertyPath("(Canvas.Left)"));130
//创建Y轴上动画131
DoubleAnimationUsingKeyFrames animY = new DoubleAnimationUsingKeyFrames();132
animY.Duration = TimeSpan.FromMilliseconds(path.Count * 100);133
Storyboard.SetTarget(animY, person);134
Storyboard.SetTargetProperty(animY, new PropertyPath("(Canvas.Top)"));135
for (int i = 0; i < path.Count; i++)136
{137
LinearDoubleKeyFrame keyFrame = new LinearDoubleKeyFrame();138
keyFrame.Value = i == 0 ? Canvas.GetLeft(person) : pathPoint[i].X;139
keyFrame.KeyTime = TimeSpan.FromMilliseconds(time * i);140
animX.KeyFrames.Add(keyFrame);141

142
keyFrame = new LinearDoubleKeyFrame();143
keyFrame.Value = i == 0 ? Canvas.GetTop(person) : pathPoint[i].Y;144
keyFrame.KeyTime = TimeSpan.FromMilliseconds(time * i);145
animY.KeyFrames.Add(keyFrame);146

147
}148
action.Children.Add(animX);149
action.Children.Add(animY);150
//添加进资源151
if (!Resources.Contains("action"))152
{153
Resources.Add("action", action);154
}155
action.Begin();156

157
}158

159
}160
/// <summary>161
/// 根据图片自动生成障碍物矩阵162
/// </summary>163
/// <param name="mapPaht">图片路径</param>164
/// <param name="gridSize">网格宽度</param>165
/// <returns></returns>166
private byte[,] PathGrid(string mapPaht, int gridSize)167
{168
BitmapSource map = new BitmapImage(new Uri(mapPaht, UriKind.Relative));169
int xLenght = (int)(map.PixelWidth / gridSize);//矩阵宽170
int yLength = (int)(map.PixelHeight / gridSize);//矩阵高171
byte[,] grid = new byte[xLenght, yLength];172
byte[] pixels = null;173
CroppedBitmap crop = null;174
for (int j = 0; j < xLenght; j++)175
{176
for (int i = 0; i < yLength; i++)177
{178
Int32Rect rect = new Int32Rect(i * gridSize+gridSize/2, j * gridSize+gridSize/2, 1, 1);179
crop = new CroppedBitmap(map as BitmapSource, rect);//取每个方块终点位置的颜色180
pixels = new byte[4];181
crop.CopyPixels(pixels, 4, 0);182
if (Colors.White == Color.FromArgb(pixels[3], pixels[2], pixels[1], pixels[0]))183
{184
grid[i, j] = 1;//为白色区域为可行路径否则为不可行路径185
}186
else187
grid[i, j] = 0;188
}189
}190
return grid;191
}192
}193
}只是简单写了一下,细节上的大家可以自己完善,根据这个原来创建地图真实太Easy了,哈哈
注:里面用的A*算法还是深蓝的,在此声明;感谢深蓝写了这么好的教程


浙公网安备 33010602011771号