XNA 2D鼠标选择

我正在使用XNA开发一个简单的2D实时策略游戏。 现在我已经达到了我需要能够单击一个单元或建筑物的精灵并且能够引用与该精灵相关联的对象的点。 根据我过去三天所做的研究,我发现了许多关于如何在3D中进行“鼠标拾取”的参考资料,这似乎不适用于我的情况。 我知道另一种方法是简单地在世界中拥有一个包含所有“可选”对象的数组,当玩家点击一个精灵时,它会根据数组中所有对象的位置检查鼠标位置。 我对这种方法的问题是,如果单位和建筑物的数量增加到更大的数量,它会变得相当慢。 (它似乎也不是很优雅)所以我还能做些什么呢? (请注意,我还研究了使用哈希表将对象与精灵位置相关联的想法,并使用二维数组,其中数组中的每个位置代表世界上的一个像素。再一次,它们似乎相当笨重的做事方式。)

对于多达数百个单位,如果点击区域是圆形或矩形,它应该足够快,只需对世界上所有单位进行线性搜索O(n)。 尤其是看到每次点击一次,而不是每帧一次。

如果您的单位不是圆形或矩形,请首先检查边界圆或矩形,如果通过则检查更复杂的边界形状。

有关更详细的答案, 这是我对类似空间分区问题的答案 。 在那里我提到了bucketed网格和四叉树作为性能优化的潜在结构。

但是,在测试并确实存在性能问题之前,您永远不应该进行性能优化!

如果您有一个管理drawabel对象的类,则可以使用静态int,每次创建新对象时都会增加该int,并将旧对象保存为drawabel对象中的Color的本地实例。 然后你可以使用.Net类型的转换器来制作它的再见数组并返回,不记得它的名字和我在手机上的火车,所以无法检查你。

当您从字节数组构建颜色时,请记住最大化alpha通道,如果您碰巧得到太多对象,则可能会超出您可以使用的索引..不知道该怎么办…可能有你所有的对象再次从0:0:0:255重新获取新颜色,因为希望一些旧的颜色不再使用:P

不确定我做了很多的意义,但因为我在火车上所有我可以给你,抱歉:)

您可以使用像素完美拾取,它可以很好地扩展到大量的对象(并且具有像素完美的优势)。

基本上,您使用每个对象的唯一颜色渲染场景。 然后将backbuffer解析为纹理并返回纹理数据,最后您只需检查鼠标下方的像素,找出鼠标所在的对象。

您可以巧妙地了解您获得的信息,您可以只请求鼠标位于其上的单个像素。

Color[] pixel = new Color[1]; texture.GetData(pixel, mousePosition.Y * texture.Width + mousePosition.x, 1); //pixel[0] == colour of the item the mouse is over. You can now look this up in a dictionary 

你应该注意不要通过这样做来阻止管道(导致CPU等待GPU渲染事物)。 执行此操作的最佳方法是在两个渲染目标之间交换,并始终从最后一帧使用的渲染目标中交换GetData,这意味着数据是一个过时的帧,但没有人有足够快的反应通知。

回复您的评论的附录。

要为每个对象指定唯一的颜色,只需为每个对象增加一个字节。 当该字节溢出时,增加另一个字节,当一个字节溢出增加另一个字节时; 然后您可以将这三个字节用作红色,绿色和蓝色。 记住将alpha保持在最大值,你不希望任何透视对象!

在XNA4中稍微改变了解决后备缓冲区的问题。 现在,您必须渲染到rendertarget并解决该问题。 要做到这一点非常简单,Shawn Hargreaves 在这里概述了这一点