我确定我做错了什么;但这一直让我疯狂了一段时间。
我做了一个小型的Silverlight游戏(旧的Galaxian克隆)。当游戏开始~90%的时候,一堆星星随机定位在游戏区域。有三种类型的恒星 - 更大的恒星更快,更小的恒星运动更慢。
看起来像这样:
大约10%的时间所有星星出现在'乐队'中
我认为值得一提的是,即使它们处于狭窄的范围内;他们并非都处于同一个位置。所以它就像它仍然生成一个随机数 - 只是一个很小的。
要重现错误,我只需在浏览器中点击“f5”即可。几乎所有时间,它都按预期工作。很少,我得到乐队。再次点击'f5'将解决问题。
没有张贴巨大的代码墙;我认为这是最相关的代码。它出现在Base类中,我的所有星星都继承自。当每个星星被创建时,它会被调用一次。
Protected Sub SetInitialPosition()
myElipse.Height = GetStarSize()
myElipse.Width = GetStarSize()
_location.X = GetRandom.Next(-1 * Settings.StarEdge, CType(GameCanvas.Width, Integer) + Settings.StarEdge)
_location.Y = GetRandom.Next(0, CType(GameCanvas.Height, Integer))
myElipse.Fill = New SolidColorBrush(GetStarColor)
End Sub
我没有看到任何错误。 GetRandom()返回一个单例Random类,我依赖于GameCanvas.Height和GameCanvas.Width是有效的 - 但同样,.Width似乎完全按预期工作。
有没有人对这种行为有可能的解释?生成随机数时是否有任何需要注意的问题?每次我单步执行代码,一切都很好,游戏按预期工作。
如果有帮助我可以发布游戏链接 (http://robdude.weebly.com/cci.html)
编辑#1:
以下是GetRandom()
Protected Shared Function GetRandom() As Random
If _random Is Nothing Then _random = New Random()
Return _random
End Function
编辑#2: 我非常感谢每个人对此的想法/建议。
答案 0 :(得分:4)
我想让这个答案尽可能通用,希望它可能对其他人有所帮助。我已经在这里整合了其他答案(以及对我的问题的实际修复),这可能对那些经历随机生成数字的奇怪行为的人有所帮助。
使用不同的随机实例
Random类的实例具有关联的种子。一般来说,您希望重用相同的Random实例或确保种子不同。如果您使用相同的种子创建了2个不同的Random实例,则第一个.Next将返回相同的结果。
<强>线程安全
Random不是线程安全的。
条件断点
我有时会忘记这是一个选择。在某些情况下,“单步执行代码”的行为将隐藏运行时出现的错误。设置条件断点是检查这一点的好方法。在我的情况下'CType(GameCanvas.Height,Integer)&lt; 750'是我使用的条件。
<强>登录
同样,对于像这样的bug,日志记录也是非常宝贵的。我不知道为什么在问这个问题之前我没有想到它。
最后,由于我不理解的原因,很少有GameCanvas.Height
的值未正确设置。我的理论是,当我创建/定位/调整GameCanvas时,我在其他地方做错了或做得不正确。
逐行逐步执行代码似乎无法解决问题。在我的情况下,比赛场地的大小是固定的;所以不是从GameCanvas控件检查大小 - 我现在从我的Settings对象中拉出它。
感谢团队调试每个人。非常感谢。
答案 1 :(得分:1)
如果GetRandom()每次都返回一个新的Random实例,那么这就解释了这个错误。你应该只有Random的实例。
如果它返回一个新实例,则新实例很有可能在重复调用时获得相同的种子值。如果种子相同,则两个不同的实例将返回相同的“随机”值。