7

以下事件可能每帧调用数百次。

public bool OnCollision(Body body1, Body body2)
{
 if(body2.Tag is Dog)
      ((Dog)body2.Tag).Bark();
}

我知道使用“is”会导致进行演员表,然后当我想用它做某事时,再次转换它。有没有更有效的方法来检查类型?我制作了一个控制台应用程序尝试“if(body2.Tag.GetType() == typeOf(Dog))”,但它似乎比使用“is”还要慢。

谢谢。

4

4 回答 4

19
 if(body2.Tag is Dog)

实际上编译为

Dog Temp = body2.Tag as Dog;
if (temp != null)

在您的代码中,您将再次进行演员阵容。更好的是:

Dog dog = body2.Tag as Dog;
if (dog != null)
{
    dog.Bark();
}
于 2008-12-18T17:55:19.907 回答
6

我会在 Body 对象上创建一个名为 Collided 的抽象方法:

abstract class Body
{
   abstract void Collision(Body other);
}

class Dog : Body
{
   public override void Collision(Body other) {
      this.Bark();
   }

   public void Bark() { ... }
}

然后在您的碰撞函数中,只需在相关物体上调用 Collision 即可。

public bool OnCollision(Body body1, Body body2)
{
   body2.Collision(body2);
}

这样,任何类型的主体都可以在发生碰撞时做任何需要的事情,您甚至可以对其进行优化以跟踪哪些主体已收到相互碰撞的通知,并减少您必须执行的函数调用的数量:

public bool OnCollision(Body body1, Body body2)
{
   // Record that these two objects have been notified of a collision
   // then when these same objects are the only two operands in subsequent calls
   // you can just short circuit the calls.
   if(!AlreadyNotifiedOfCollision(body1, body2))
   {
      body1.Collision(body2);
      body2.Collision(body1);
      NotifiedOfCollision(body1, body2);
   }
}

当然,必须进行经验测试以验证此检查是否比实际调用两次更快...

于 2008-12-18T18:12:25.910 回答
1

这样的方法是否可行或有用?

public interface ICollidable
{
    void OnCollision();
}

public abstract class Body : ICollidable
{
    public abstract void OnCollision();
}

public class Dog : Body
{
    public override void OnCollision();
    {
        Bark();
    }
}

public Boolean OnCollision(ICollidable a, ICollidable b)
{
    b.OnCollision();
}
于 2008-12-18T18:12:28.780 回答
0

通用碰撞方法怎么样?那么就不需要继承了。只是一个界面。

public bool OnCollision<TA,TB>(TA a, TB b)
    where TA : ICollidable
    where TB : ICollidable {
    a.Collision(b);
}
于 2009-06-28T18:20:22.100 回答