技术开发 频道

开发Silverlight游戏教程:副本地图

    【IT168技术文档】
转载自:深蓝色右手的博客

    前面几节详细的讲解了游戏地图的完整构造,比较有难度的是关于地图内层如障碍物的实现。A*算法往往能让众多的初学者望而止步,斜度α地图则更需要一定的几何知识及抽象思维。很多朋友就问了:什么年代了,都在说面向对象、提高开发效率,难道就没有大众化可以让各层次能力的朋友们都能轻松制作地图引擎的方法吗?大家是否还记得上一节中遗留的一个小悬念,杀手涧就是它了:神奇的副本地图。

     大家先看上图,左边的是地图表现层,它的尺寸为800*600。右边的则是我通过Photoshop在原图基础上勾勒出来的该地图的副本,同样它的尺寸也为800*600。这里特别要提的是该副本是由简单纯色调组成的,因此能够压缩到极小的容量,几乎忽略不计,这是它能作为我们得力工具的前提,也是Silverlight制作基于网页游戏的必要条件。好了,接下来我们详细介绍一下此副本:大家对照原图很容易会发现它上面的黑色其实代表的就是地图中的障碍物,那大片的白色区域呢?其实就是我们可以任意通行的区域了。至于黄色,聪明的朋友应该也不难猜到,它代表的是地图中的传送点。当然,您还可以在此副本中增加例如红色代表陷阱,绿色代表特殊NPC等等。是否觉得像画画一样的?嘿嘿,这就是我主张的面向对象的游戏编程创新思想了。到此地图副本制作完成了,那么该如何利用它呢?

    精华又出现啦,来看看优美的拾色方法(此时,我们需要将Deeper.jpg副本图片按照第五节中的方法添加进Map文件夹中,以便被下面方法更好的识别):

 

 

//图片拾色

private Color pickColor(BitmapSource bitmapsource, int x, int y) {

CroppedBitmap crop = new CroppedBitmap(bitmapsource as BitmapSource, new Int32Rect(x, y, 1, 1));

byte[] pixels = new byte[4];

try {

crop.CopyPixels(pixels, 4, 0);

crop = null;

} catch (Exception ee) {

MessageBox.Show(ee.ToString());

}

//蓝pixels[0] 绿pixels[1] 红pixels[2] 透明度pixels[3]

return Color.FromArgb(pixels[3], pixels[2], pixels[1], pixels[0]);

}

    太强大了,有了它就好比吕布拿上方天画戟-游刃有余!(该方法只能在WPF使用,至于如何在Silverlight中调用,Silverlight3.0将会给您一个完美的解决方案。^_^)

    副本地图的作用是非常凶猛的,在它上面我们可以自由绘画出红黄蓝绿青橙紫等等N多颜色来描绘不同的地图属性,然后实现类似以下操作:

    1、如果主角采到的点是黑色就相当于主角碰到了障碍物,这时主角的动作即为停止。

    2、如果是传送点,则根据坐标范围(或其他条件等)判断是传送到哪张地图;

    3、如果是陷阱则将触发什么事件,如去血或被传送,或是刷怪等等;

    4、当然还可以有其他颜色,假如游戏中有飞行坐骑等元素存在(实现2D地图中的三维空间),那么同样可以用一个例如蓝色来代表空中障碍物区域,或用紫色来代表陆地和空中均属的障碍物,这些都是相当灵活的。

    5、白的则为可以通行,主角在上面可以正常移动。

    更美妙的是,此方法可以与A*寻径相结合,从而创造出更加优美的角色移动(例如帝国时代中采取的就是它独特的改进型A*,所以根据游戏自身的特点您可以对A*进行优化,Gameres论坛有很多高手的文章,大家可以参考一下)。接下来大家来回忆一下第七节讲到的A*寻径算法,此方法找到的路径中如果有经过障碍物倒还好,但是如果没有障碍物的,那么此路径全程中将或多或少会有些折叠的地方(如下图)。
 

    人类总是希望将东西做得完美导致本节的重点出现了:如何通过神奇的副本地图来优化A*寻路,让它更加贴近真实呢?这里我们需要先理解一个关键知识点:主角所处的地图中所有的点与副本地图中所有的点都是一一对应(映射)的关系。例如假设主角在地图中的坐标为(356,248),那么此坐标对应副本地图坐标也同样为(356,248),这样我们就可以通过函数方法,将主角的坐标点作为参数在副本地图中找该点的颜色,看看颜色分别是黑的,还是白的,或是黄的等等,从而映射回主角的地图可知主角当前处于地图中是障碍物,还是可同行区域,或是传送点等等。了解了原理后,下面我就用代码来实现它:

    首先我们需要写出两种移动方法(具体代码就不列出来了,在本教程的目录中有下载):第一种我定义为NormalMove移动方法,它就是我第一节中讲到的点与点之间的直线移动,在此方法中我稍微改动了一些,使坐标定位到主角的脚底,并且将移动目标终点记录到Point Target中。第二我将之定义为AStarMove移动方法,它就是我前面几节讲到的A*寻路方式。设置好后,我们就可以根据从副本地图中获取的点的颜色判断来调用相应的移动模式了。

0
相关文章