在上次的文章中,咱们作了一个最简单的基本的追逐与闪躲的功能,就是根据猎物坐标来修改追击者的坐标,使得二者之间的距离渐渐缩短。上次的文章中,咱们主要是根据物体屏幕坐标改变,来产生追逐动画,他们改变的坐标位子是连续的,也就是坐标点与坐标点的变化,这种叫作
连续环境,可是在游戏中用得更普遍的是另外一种方式,
砖块环境。今天,咱们就来一块儿在
silverlight中实现下砖块环境下的追逐与闪躲。
何为砖块环境?html
在砖块环境构成的游戏中,游戏屏幕会被切割成不连续的砖块:正方形,三角形,六边形等等。通常会选择正方形,由于正方形在处理上面相比其它形状更简单。函数
有了切割成的方块后,整个游戏画面就像是这个样子的:测试
游戏玩家的位置会固定在某个砖块上面,移动的时候都是以砖块为单位,而且前进方向也是有限制的,而在上次文章中的连续环境下,是以坐标点做为游戏玩家角色的位置,这样能够在任何方向移动。而砖块环境下,若是以正方形为基本单元,那么,游戏玩家就只能有八个方向的运动以下:动画
其实,无论是连续环境仍是砖块环境下,其基本追逐闪躲代码是通用的,只不过,上次咱们是以点为移动的基本单元,而今天,咱们是以砖块为基本单元,如:上次移动一步是从坐标(0,0)移动到坐标(1,1)。而如今移动一步是从第一个砖块移动到下一个砖块。好了,基本原理就是这样,那么在silverlight中咱们又该如何实现呢?spa
我是这样实现的,只是提供一个参考,并非最好的,你们或许有更好的办法:)htm
既然要实现砖块环境的移动,可是咱们清楚,他的本质仍是和连续环境下的移动同样,为了重用上次文章中的核心追逐与闪躲代码,咱们只要把上次移动坐标的结果反映到移动砖块的结果上面就好了。能够这么想,经过一个方法,放大坐标移动的效果,若是你移动一个坐标点,如(1,0)到(2,0);将这个操做放大到从第一个砖块移动到下一个相对应的砖块。这样在屏幕上产生的效果将会被放大,以前只移动一点点,而放大后就是移动一个方块的距离,由此咱们须要一个逻辑坐标集合和屏幕坐标集合并经过一些坐标转换方法,来使得他们之间产生通讯。游戏
转换函数以下:get
- public Point ChangeLogicToViewP(double x,double y) //把逻辑坐标转换成屏幕坐标
-
- {
-
- x = 350+x*60;
- y = 10+y*60;
-
- return new Point(x,y);
-
- }
里面的数字350,60,10 这要根据你本身设定的砖块大小和屏幕边距来进行肯定,具体能够本身测试。这里咱们设定的砖块长宽为60,而画布左边距是350,因此对应把坐标(0,0)换算到屏幕上第一个砖块的位置是350+x*60.源码
追逐代码和上次的相似:class
- public void Catch(double monX, double monY, double humX, double humY)
- {
- monsterX = GetRow(monX);
- monsterY = GetColunm(monY);
- humanX = GetRow(humX);
- humanY = GetColunm(humY);
-
- if (monsterX < humanX)
- {
- monsterX++;
- monsterX=SetRow(monsterX);
- humanX = SetRow(humanX);
- }
- else if (monsterX > humanX)
- {
- monsterX--;
- monsterX=SetRow(monsterX);
- humanX = SetRow(humanX);
- }
- else if (monsterX == humanX)
- {
- monsterX = SetRow(monsterX);
- humanX = SetRow(humanX);
- }
- if (monsterY > humanY)
- {
- monsterY--;
- monsterY=SetColnm(monsterY);
- humanY = SetColnm(humanY);
-
- }
- else if (monsterY < humanY)
- {
- monsterY++;
- monsterY=SetColnm(monsterY);
- humanY = SetColnm(humanY);
- }
- else if (monsterY == humanY)
- {
- monsterY = SetColnm(monsterY);
- humanY = SetColnm(humanY);
- }
-
- }
其中的SetRow()和SetColnm()方法也是坐标转换方法,具体以下:
- public double SetRow(double x)
- {
- return x * 60 + 350;
- }
- public double SetColnm(double y)
- {
- return y * 60 + 10;
- }
好了,今天就写到这里,具体源码就不贴出来了,这里我只是提供下我本身的思路,相信你们会有更好的方法,并且我代码写的有点乱,如何有须要的朋友能够留言,到时候我整理下,到时候发到大家邮箱:)
测试效果:http://www.ophoneba.com/SL/SLAI-2.html