2011-11-01 65 views
8

长时间读者首次海报。请温柔。“自觉”课程?

我热衷于在VB.net中创建游戏。作为一名业余爱好程序员,我可以免费游戏。由于我没有经过正式培训而最懒散,所以我尝试着学习正确的编程原则,并在编程时遵循它们,如OOP。然而,有些事情我明显错过了自学,也许我会知道我是否受过正式的教育。

一旦这样的问题真的成了我的祸根,那么不同类别(从现在开始被称为对象)'彼此'了解',而无需编程具体交互(请在此留言......请......)

好的想象这,你有一个空间的游戏,以下对象

  • clsShip
  • clsMissile
  • clsAsteroid
  • clsSpaceJunk

现在,这些对象中的每一个都有一个Health,X,Y和Z私有成员和属性,它们都是为了参数而从clsSpaceEntity继承的。现在他们之间的编程冲突的一个方法是将代码从下面的逻辑在游戏主循环

为每艘船舶
检查每个clsMissile在列表中的一个列表,看它是否与它,如果碰撞因此,降低健康
检查每个clsAsteroidin列表,看它是否与它,如果是碰撞时,降低健康
检查每个clsSpaceJunka列表,看它是否与它,如果是碰撞时,降低健康
...等对等为每个对象 未来

ECT ECT等...

现在,如果你说的是简单的例子以上,但我的一些游戏有几千万甚至,在这个基本的方式进行交互的对象数百这可能还好缝。现在

我的问题有经验的程序员在那里。

是否有面向对象的方式来执行下列操作...

为从clsSpaceEntity继承每一件事情
针对继承此类型(除本身)所有其他对象 检查,如果他们相碰,然后降低健康
未来

这种能力对于一个类型的对象/类或什么的,要作另一个“识别”和它们是如何相同/不同的互动会救我吨,吨和编码吨。

任何援助/帮助或反馈,这将是非常赞赏。感谢您的时间,对于长时间的阅读感到抱歉。

+7

不要使用匈牙利符号('clsWhatever')。 – SLaks

+1

它看起来像你试图实现适当的问题分离。使用更多的OOP概念,您可以制作精美分离的逻辑,而无需处理每种类型对象的巨大方法。祝你好运! – SLaks

+1

稍微偏离主题,但您对类和对象似乎有点困惑。虽然它们是相关的,但它们并不是一回事。这个评论框对于完整的解释有点小,但是阅读差异会让你的生活更轻松。 –

回答

7

对于每个派生对象,您应该制作一个包含所有实体的单个List(Of SpaceEntity),而不是单独的List(Of T)

然后,您可以制作嵌套的For Each循环,循环遍历每对实体并进行碰撞检查。 (后If x <> y检查)

可以进一步提高通过给SpaceEntity一个MustOverride函数来处理与其他物体碰撞,而不会为每个实体单独的逻辑污染你的碰撞回路设计。
您应该使用visitor pattern来允许实体对与其他不同类型实体的冲突做出不同反应。

请注意,每次碰撞将被发送到两个分开碰撞的对象;你需要在你的逻辑中处理。

2

如果我正在编写处理单船,单导弹,小行星等的逻辑,那么这个逻辑应该明确属于相应的类。

如果我正在编写处理多个对象或甚至更糟糕的多个不同类型的对象的逻辑,我会倾向于将该逻辑放在表示更高级别概念的类中。

例如,您可能有一个包含SpaceEntity's集合的Universe类。还有一个Universe.FindCollisions(),它返回Collision对象的集合。

public class Universe { 
    private IEnumerable<SpaceEntity> _entities; 

    public IEnumerable<Collision> FindCollisions() { 
     foreach(var e1 in _entities) { 
      foreach(var e2 in _entities) { 
       if (e1.CollidesWith(e2)) { 
        yield return new Collision(e1, e2); 
       } 
      } 
     } 
    } 
} 

另一种方式来解决它可能是有接受SpaceEntity在它的构造函数的集合,是地方的具体逻辑生命CollisionCalculator类。

public class CollisionCalculator { 
    public IEnumerable<Collision> Collisions {get; set;} 

    public CollisionCalculator(IEnumerable<SpaceEntity> entities) { 
     // logic to build the Collisions collection goes here 
    } 
} 
+0

嵌套的foreach循环将为每个重叠的实体对返回两个碰撞。一个是导弹与岩石碰撞,一个是岩石与导弹碰撞。您可能需要过滤掉这些,这取决于您的冲突解决方案的处理方式。 – tcarvin

+0

可能值得注意的是,由于对象数量变大(超过几百),双重嵌套for循环将变得不切实际。如果物体之间存在一定距离以保证它们不可能发生碰撞,将宇宙细分为大于这些区域的区块可能会有所帮助,并且保留至少部分位于每个区块中的物体列表。在3d空间中使用简单的分区,一些对象可能不得不出现在最多八个列表中,但是测试100组十个对象进行冲突将比测试一组1,000个更快。 – supercat

+0

顺便提一下,将三维空间划分成不会超过四个区域(而不是八个)的区域是可能的,也不是过分困难。如果将Y舍入到最接近的整数将产生奇数,则将0.5加到X上。如果将Z舍入到最接近的整数将产生奇数,则将X和Y都加0.5。然后将所有三个坐标四舍五入为整数。空间坐标和XY值之间的映射表明,空间被分割为单位立方体,以便任何点的四分之一单位内不超过四个。 – supercat