最近看了《游戏编程模式》这本书,里面有一篇空间分区的文章,看了心里痒痒,决定去尝试实现一下。文章后面会给出整个学习参考的链接。
实现的效果如下,我们有一个很大的场景,场景有许许多多的敌人。红色的点代表是玩家,黑色的点代表是敌人。在这样的一个大量敌人的情景下,我们不可能在玩家或敌人寻找身边的攻击对象时穷尽所有的对象。因为我们要建立空间分区,只遍历某个对应区的对象。在图下中,红点中遍历红框中的黑点对象,其他一律不遍历。
接下来我直接放代码了,主要采用了四叉树,如果对于一些不懂的地方断点调试下就可以了,并没有涉及到很高深的算法,不要想得太难。
其中也实现了红点在分区边缘遍历另外一个区的敌人的漏洞。
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 5 /// <summary> 6 /// Rect的扩展方法类 7 /// </summary> 8 public static class RectExtension 9 { 10 /// <summary> 11 /// 计算点到Rect的border的距离,若点在Rect内则返回0 12 /// </summary> 13 /// <param name="rect"></param> 14 /// <param name="pos"></param> 15 /// <returns></returns> 16 public static float PointToBorderDistance(this Rect rect, Vector2 pos) 17 { 18 float xdisance; 19 float ydisance; 20 21 if (rect.x <= pos.x && pos.x <= rect.xMax) 22 { 23 xdisance = 0; 24 } 25 else 26 { 27 xdisance = Mathf.Min((Mathf.Abs(pos.x - rect.width)), (pos.x - rect.x)); 28 } 29 30 if (rect.y <= pos.y && pos.y <= rect.yMax) 31 { 32 ydisance = 0; 33 } 34 else 35 { 36 ydisance = Mathf.Min((Mathf.Abs(pos.y - rect.height)), (pos.y - rect.y)); 37 } 38 39 return xdisance * xdisance + ydisance * ydisance; 40 } 41 }