2

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

4

3 回答 3

5

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

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

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

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

于 2010-12-24T10:14:34.267 回答
1

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

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

不确定我是否说得很有道理,但是因为我在火车上,所以我只能给你,对不起:)

于 2010-12-30T12:39:51.193 回答
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 渲染事物)。最好的方法是在 2 个渲染目标之间进行交换,并且始终从您上一帧使用的渲染目标中获取数据,这意味着数据是一个过期的帧,但没有人有足够快的反应来注意到。

附录以回应您的评论。

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

在 XNA4 中为了解决 backbuffer 做了些许改动。现在您必须渲染到渲染目标并解决它。要做到这一点非常简单,Shawn Hargreaves在这里概述了

于 2010-12-24T11:32:23.437 回答