XNA 2D鼠标选择

时间:2010-12-24 06:50:35

标签: c# xna 2d mouse-picking

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

3 个答案:

答案 0 :(得分:5)

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

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

有关空间分区的更详细答案here's my answer to a similar question。在那里我提到了bucketed网格和四叉树作为性能优化的潜在结构。

但是,在测试并且实际上出现性能问题之前,您绝不应该进行性能优化!

答案 1 :(得分:1)

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

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

不确定我有多大意义但是因为我在火车上就是我能给你的所有东西,抱歉:)

答案 2 :(得分:0)

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

基本上,您使用每个对象的唯一颜色渲染场景。然后将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<Color, item>

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

回复你的评论附录。

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

要解决后备缓冲区在XNA4中略有改变。现在,您必须渲染到一个rendertarget并解决它。要做到这一点非常简单,并由Shawn Hargreaves here

概述