Using Generic Functions for collision detection in C# / XNA

别等时光非礼了梦想. 提交于 2019-12-13 02:29:16

问题


I am making a physics engine in c# / XNA, I have three basic objects...

Sphere Cube Plane

that are all derived from

GameObject

I store all my objects in a list of GameObjects and I would like to loop through this list and be able to call a CheckCollision function that will go to the correct function for each pair of objects

eg

go is a Sphere,

go2 is a Sphere

if(CheckCollision(go, go2))
{
  //do stuff
}

bool CheckCollision(Sphere one, Sphere two)
{
  //Check Sphere to Sphere
}

bool CheckCollision(Sphere sphere, Plane plane)
{
  //Check Sphere to Plane
}

and I would like it to just go to the correct function withour having to use if checks.

Thank you.


回答1:


You could use virtual dispatch:

abstract class GameObject
{
    abstract bool CheckCollision (GameObject other);
    abstract bool CheckCollision (Sphere other);
    abstract bool CheckCollision (Cube other);
    abstract bool CheckCollision (Plane other);
}

class Sphere : GameObject
{
    override bool CheckCollision (GameObject other) { return other.CheckCollision(this); }
    override bool CheckCollision (Sphere other) { /* ... implementation ... */ }
    override bool CheckCollision (Cube other) { /* ... implementation ... */ }
    override bool CheckCollision (Plane other) { /* ... implementation ... */ }
}

class Cube : GameObject
{
    override bool CheckCollision (GameObject other) { return other.CheckCollision(this); }
    override bool CheckCollision (Sphere other) { /* ... implementation ... */ }
    override bool CheckCollision (Cube other) { /* ... implementation ... */ }
    override bool CheckCollision (Plane other) { /* ... implementation ... */ }
}

class Plane : GameObject
{
    override bool CheckCollision (GameObject other) { return other.CheckCollision(this); }
    override bool CheckCollision (Sphere other) { /* ... implementation ... */ }
    override bool CheckCollision (Cube other) { /* ... implementation ... */ }
    override bool CheckCollision (Plane other) { /* ... implementation ... */ }
}

EDIT

Consider what happens when you have this:

GameObject go1 = new Sphere();
GameObject go2 = new Cube();
bool collision = go1.CheckCollision(go2);
  • The call goes to the abstract GameObject.CheckCollision(GameObject) method on the sphere.
  • Virtual dispatch means that we go to Sphere.CheckCollision(GameObject)
  • Sphere.CheckCollision(GameObject) calls the abstract GameObject.CheckCollision(Sphere) method on the cube.
  • Virtual dispatch means that we go to Cube.CheckCollision(Sphere)!

Therefore, no type-checking if statements are necessary.

EDIT 2

See Eric Lippert's answer at https://stackoverflow.com/a/2367981/385844; the first option -- the visitor pattern -- is essentially the approach outlined above. Eric's other answer at https://stackoverflow.com/a/9069976/385844 also discusses this issue.




回答2:


I fear that this is not possible, unless you approximate your shapes with polygons, which would allow a generic approach. If you work with the exact mathematical representations then you will need to have special solutions for the different pairings. If you give numbers to the different shape types (1, 2, 3) you could represent a pair with 10* go.Number + go2.Number and use this number in a switch statement.

Note also that your approach has an O(n^2) performance where n is the number of objects. Consider using a more appropriate data structure than a list. K-D-trees are often used in order to store objects in a k-dimensional space. They are often used in conjunction with bounding boxes of the graphical objects. Each object would have a method or property yielding a bounding box. K-D-trees would reduce the number of required collision checks. See k-d tree on Wikipedia.



来源:https://stackoverflow.com/questions/9164612/using-generic-functions-for-collision-detection-in-c-sharp-xna

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!