地图比较复杂,所以我就直接将一张地图加载进去,还不错,省却了贴片步骤。
【卷屏】
由于地图很大,比游戏显示窗口要大,所以这里就需要实现【卷屏】效果,一开始摸不着头脑,试了很多种方法,有些是可以,但是过于复杂,涉及到了C#语言特性,比如委托和事件,这个不具备其他语言通用的方法,因此肯定存在更加广泛的技术。
网上搜了些资料,有了大概的思路,卷屏的效果的原理是:当人物在一个区域内,是通过改变人物在屏幕上的坐标来实现走动效果,当人物离开一个区域后,是通过地图反向移动之后实现人物“走动”的效果。
所以,一开始,就应该准备一个这样的区域,假设是scrollRect,它的中心应该处于屏幕的中心,区域大小应该小于游戏的屏幕。然后这样进行逻辑判断:如果人物位于这个区域内,以右向移动为例,有Role.X+=Role.Speed。当人物离开这个区域,有Map.X-=Role.Speed。当然,还要考虑到人物走到地图的边角处,此时也是只有人物移动。
效果如下:
【地形障碍】
在实现了卷屏效果之后,障碍物的设置成为了重点之一(地图遮罩也是很重要的,部分实现中)。
怎么实现呢?可以先用地图编辑器来设置障碍物的座标,保存在文件中,这些坐标再读取到一个二维数组中collision[][]注意,这个数组是压缩过的,毕竟只要将障碍物的座标设置为1,其他为0表示可通行的。(该数组表示地图压缩过后的座标,以减少内存使用量)
之后只要判断人物在该数组中的索引是否是1就可以了。当然,判断的时候记得放大回原来的座标系索引。
如collision[i][j]=1,人物座标是rolex,roley,放大倍数是20,又因为实现了卷屏效果,所以有mapx,mapy作为地图座标,可知道i=(rolex-mapx)\20,j=(roley-mapy)\20。,但是这样有个bug,就是人物在碰到障碍物的时候,下一次移动的时候会没有反应,因为该方向已经处于障碍物座标了,例如当我走到一个障碍格子处的时候,我在向上走,如果还是障碍格子的话,此时我再向原来的方向走就会出现无反应的bug,这就需要提前预测,比如前方一格的障碍物是否存在,比如向右走,前方有个障碍物,因此有collision[i+1][j]=1。
效果如下:人物正前方有障碍格子,所以不能移动。
【地形遮挡】
下一步就要实现遮挡了,这个想了好久,想出了两个,原理还是挺简单的。
在这里,我截取了一层用作遮挡,就是人物可能被遮挡的块图用PS分离出来,形成新的图层,并且设置它的图层深度比人物大,这样人物走到这些地方就会呈现被遮挡的效果。而且这一层是和最底层背景图片一起移动的(不然就会出现显示错误,如遮挡层一直停留在屏幕的绝对位置,而不是相对于地图的位置)。
效果如下:
但是这样出现的很大问题是,因为这一层的深度是固定的,人物层的深度也是固定的,这时就会有个bug。举个例子,比如人物走到石头后面就会被石头遮挡,这时是正确的显示。但是,当人物走到石头前面,人物应该挡住石头,但是事实上还是人物被石头挡住。因此需要动态设置某一层的深度。
和贴片的方式不同,一整张图的地图需要采用新的方式,也是想了很久才想出来,根据以前接触的3D开发,想到里面3D模型多了一个Z轴,而2D没有Z轴,不过最后图片渲染的顺序就是给图片设置深度来改变的,比如深度大的贴图在深度小的贴图的下方,相反也可以,只需要设置排列的方式就可以了,也可以说是根据了画家算法。
这里,我动态地改变了人物层的深度,而这个深度是通过Y轴改变的,可以发现,Y轴大的物体是处于较前面的,所以动态改变Y轴的同时可以修改其深度值。
待续^_^
//注意,以上的素材都是我从深蓝色右手的博客上弄下来的,特此声明。