c# – 对于水管连接游戏,如何正确检查所有4个相邻的网格而无需回流或使用Update() LateUpdate()?

c# – 对于水管连接游戏,如何正确检查所有4个相邻的网格而无需回流或使用Update() LateUpdate()?,第1张

概述我正在尝试编码的游戏是一个管道连接游戏,其中有4个水源(左上角,左下角,右上角和右下角),目标是将它们连接到位于最顶行的~11个建筑物的网格. 我设置的网格是一个21 x 9的32x32px正方形列表,每个正方形都包含对null“Pipe”类的引用.我还在Grid< 0>处制作了一个水源(基本上是“hasWater = true”).用于测试目的. 这是我如何做我的Pipe类的插座标记: ` p 我正在尝试编码的游戏是一个管道连接游戏,其中有4个水源(左上角,左下角,右上角和右下角),目标是将它们连接到位于最顶行的~11个建筑物的网格.

我设置的网格是一个21 x 9的32x32px正方形列表,每个正方形都包含对null“Pipe”类的引用.我还在GrID< 0>处制作了一个水源(基本上是“hasWater = true”).用于测试目的.

这是我如何做我的Pipe类的插座标记:

`  public class Pipe {   bool pipehastop; // top outlet flag   bool pipehasRight; // Right outlet flag   bool pipehasBottom; // Bottom outlet flag   bool pipehasleft; // left outlet flag   bool hasWater; // To determine pipe color and whether it can spread to other pipes   bool outletCount; // No. of outlets (I pipe has 2,T pipe has 3,etc)   bool connectedCount; // No. of outlets connected to adjacent grID's outlet   }

旋转是单独完成的,当我按下鼠标中键时,它将根据管道类型(按预期工作)更改标志

当我没有放置管道时,默认情况下实例化的网格方块为空.当前的系统是我将按热键选择管道,如果需要可以旋转它,然后通过单击将管道放置到网格上,将空引用转换为选定的管道变体.因此,在我的代码中几乎无处不在,我需要为管道添加“if!= null”:(

我目前正在使用for循环首先水平遍历每个网格方块然后垂直 – 逻辑是检查每个相邻网格是否匹配标志以及相邻网格是否“hasWater”,如果所有返回true,那么GrID-in-question将现在有了水.

for(int y = 0; y < rows; y++) {        for(int x = 0; x < columns; x++) {            int gridindex = (y*columns) + x; // Horizontal 0,1,2,etc                if(y > 0 && GrID[gridindex - columns].pipe != null)                    if(GrID[gridindex - columns].pipe.pipehasBottom == true // Check if above grID has bottom flag                      && GrID[gridindex].pipe.pipehastop == true // Check if current grID has top flag                      && GrID[gridindex - columns].pipe.hasWater == true) { // Check if above grID has water                      GrID[gridindex].pipe.hasWater == true;                      }            }    }

我重复一遍右边,底部和左边的其他3个相邻的瓷砖.

起初我遇到了一个“鬼”水管问题,当管道链断开时,分离的管道将检查仍然有水的相邻网格并重新获回水,然后整个链条确实每组2个或更多分离的管道将自我维持,除非我自己移除管道,然后只有它没有水网检查,因此没有水.

我通过在检查循环之前运行一个方法将所有pipe.hasWater变为false然后运行相邻检查来进行迷你修复

然而,由于检查循环的水平性质,我坚持使用,当一切都是假的并且它逐行检查时,在一个有水的网格上放置一个新管道将不会检查它并将新管道放置到有水的网格左边也不会检查它.我无法删除“将所有水变为假”的方法,因为它会再次导致“鬼水管”问题.

我已经尝试了几天找到一个解决方法,这是我能想到的最好的…而且大多数管道检查逻辑都在Update()和LateUpdate()下……当我不做的时候它要么中途检查要么在随机的地方休息.

对于这个看似简单的检查,我似乎无法找到平衡的解决方案.

感谢您的阅读,请帮助我了解这个动态管道检查逻辑!我会继续寻找解决方案.

解决方法 您可能需要的是一种更好的算法来检查有水的管道的连通性.我的第一反应是制作一个算法,该算法基本上遵循来自源的水流并填充每个管道的hasWater标志.如果瓷砖被移除/添加到正确重新计算(如果有水),您可能希望运行此项.我在这里伪代码的是 breadth first search.

在伪代码中:

reset all hasWater flags to false//Use a queue object to place the pipes that we are declaring as having water//but that we still need to check if they have any neighbors that will get watervar pipesWithWatertoprocess = new Queue();//seed the queue with pipes that connect to a water source (IE. one of the sources in the corners)foreach waterSource in waterSources    if exists an adjacent pipe that has an outlet that connects to the water source        if pipe does not have water already            add pipe to pipesWithWatertoprocess queue            flip the has water flag to true        end     endendwhile pipesWithWatertoprocess queue has items    var currentPipe = pipesWithWatertoprocess.dequeue()    for each adjoining tile to the currentPipe        if tile has pipe (newPipe) and newPipe connects to currentPipe            if newPipe does not have water                flip the hasWater flag                add newPipe to the pipesWithWatertoprocess queue            end        end    endend

假设您有这样的地图:

S-A-B-D-  |   |  C-  |

(线是连接,S是水源).

这种最终发生的方式是从水源开始并将管道A添加到队列中.然后你看一下队列,看看有什么东西要处理.所以你拿A出去看看它的邻居.如果B和C连接到A,则声明B和C有水并将它们添加到队列中(因为现在需要检查所有邻居).然后你做B. B.添加D.然后你做C,但是没有任何管道连接到C.然后你做D,它也没有添加管道.然后你就完成了,所有相关的东西都会显示为有水.

总结

以上是内存溢出为你收集整理的c# – 对于水管连接游戏,如何正确检查所有4个相邻的网格而无需回流或使用Update()/ LateUpdate()?全部内容,希望文章能够帮你解决c# – 对于水管连接游戏,如何正确检查所有4个相邻的网格而无需回流或使用Update()/ LateUpdate()?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1231199.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存