最近做了一个圈地的游戏,整个游戏的核心就是圈地算法的实现,对于算法这一块我真的是不擅长的很,尝试了八连通算法,但是太卡了,而且限制也比较多,不能实现。又尝试了计算机图形学中的X扫描算法和Y扫描算法,可是在某些情况下,圈地区域会漏掉,因为有些时候,圈的地是不能围成一个圈的,也就实现不到扫描算法。可能是自己才疏学浅,想不到这特殊情况下该如何处理,多番尝试也还是会有偶现的bug。最后灵光闪现想了个比较蠢的方法,就是相对而言计算量有点大,但是却能够实现预期的效果。在这里标记一下,如果能帮助到人是再好不过,不能的话我也只是做个记录。
在圈地游戏中我选择的是tiledMap。tiledMap还是很多坑的,比如说我用的tiledMap版本1.1.5。creator版本用的是1.9.2。在tiledMap中,添加图块,选中图块的渲染到层上的时候,把鼠标停在该图块上左下角就会显示图块的坐标加gid值,但是这个gid值和creator中的gid值却不一样,就是说tiledMap的gid值是从0开始的,但是creator中却始终比tiledMap的gid值大1,也就是说在creator设置gid值为1 的时候,显示的是你图块id=0的纹理。第二点就是切图的时候会有白线闪烁,很烦,在红米手机上尤为显著,某些手机上却不存在这样的情况。解决办法就是把单个图块画的大一点,中间留上缝隙。这里官方论坛提供的方法可以参考一下,也许解决了呢。我反正没解决,大概有那么一点用吧。
cc.macro.FIX_ARTIFACTS_BY_STRECHING_TEXEL = 1; //更改libcocos2d库的ccConfig.h的宏,
cc.director.setProjection(cc.Director.PROJECTION_2D);
cc.macro.ENABLE_WEBGL_ANTIALIAS = false;
cc.loader.loadRes("res", cc.Texture2D,function (err, tex) {
tex.setAliasTexParameters();
});
圈地算法的实现呢,我的思路是这样的,首先记录自己的领地上下左右四个方向的最大值。在离开自己领地的时候,记录走过的路径值,然后回到自己的领地的时候,首先将自己走过的路径设为自己的领地,然后更新领地的四个方向最大值,遍历自己的领地,如果当前领地区域内有不是自己的领地的格子,查找这个格子四个方向是否有自己领地直到尽头,找到就跳出。如果四个方向都有的话就说明被包围了,然后就肯定是被圈到了。如此循环直到遍历结束。遍历tiledMap的gid值是很卡的,有兴趣可以去看一下源码实现。我这样的方法,计算量相对比较大,在电脑上确实一点都不卡,但是在手机上,就显得有点卡顿了。所以我做了一个分帧处理的操作,如果循环次数过多,就延时0.01再去计算,这样将压力平均的分担开来,也就不会卡顿了。视觉上也不会有不好的体验。下边是我的实现代码,仅供参考。
myFillMethod(){
let self = this;
//更新领地边界值
for(var i = 0; i <self._myWalkList.length;i++){
if(self._myWalkList[i].x > self._myCityMaxX){
self._myCityMaxX = self._myWalkList[i].x;
}
if(self._myWalkList[i].x < self._myCityM