Question

I'm programming a 3D XNA game and I'm struggling to understand how to implement a momentum-like collision between my two players. Basically the concept is for either player to hit the other and attempt to knock the opponent off the level (Like the Smash Bros games) to score a point.

    //Declared Variables
    PrimitiveObject player1body;
    PrimitiveObject player2body;
    Vector3 player1vel = Vector3.Zero;
    Vector3 player2vel = Vector3.Zero;

    //Created in LoadContent()
    PrimitiveSphere player1 = new PrimitiveSphere(tgd, 70, 32);
    this.player1vel = new Vector3(0, 135, -120);

    this.player1body = new PrimitiveObject(player1);
    this.player1body.Translation = player1vel;
    this.player1body.Colour = Color.Blue;

    PrimitiveSphere player2 = new PrimitiveSphere(tgd, 70, 32);
    this.player2vel = new Vector3(0, 135, 120);

    this.player2body = new PrimitiveObject(player2);
    this.player2body.Translation = player2vel;
    this.player2body.Colour = Color.Red;

    //Update method code for collision
    this.player1vel.X = 0;
    this.player1vel.Y = 0;
    this.player1vel.Z = 0;

    this.player2vel.X = 0;
    this.player2vel.Y = 0;
    this.player2vel.Z = 0;

    if (player1body.BoundingSphere.Intersects(player2body.BoundingSphere))
    {
        this.player2vel.Z += 10;
    }

As you can see all I'm doing is checking for Player1's bounding sphere and when it intersects with Player 2's then player 2 will be pushed back on the Z axis, now obviously this just wouldn't work and isn't very intuitive and is where my problem lies as I'm buggered trying to work out how to come up with a solution, what I want happening is when either player collides with the other they basically swap vectors giving it that bounce effect I'm looking for and not just affecting one axis but both the X & Z.

Thanks for taking the time to read and I'll be grateful for any solutions that anyone can think of.

Notes: PrimitiveSphere if you're wondering is using (graphics device, diameter of the sphere, tesselation).

Was it helpful?

Solution

Basically, in a collision like the one you are trying to do, you want an elastic collision, in which both the kinetic energy and momentum are conserved. All momentum (P) is is mass * velocity, and Kinetic Energy (K) is 1/2*mass*velocity^2. In your situtation, I'm assuming everything has the same mass. If so, K = 1/2 * v^2. So, Kf = Ki and Pf = Pi. Using the kinetic energy, the velocity's magnitudes of the players are swapped. And as long as the collisions are head on (which based on your code I assume you're fine with), the players will swap directions.

So you could do something as simple as this:

if (player1body.BoundingSphere.Intersects(player2body.BoundingSphere))
{
    Vector3 p1v = this.player1vel;
    this.player1vel = this.player2vel;
    this.player2vel = p1v;
}

This should create a fairly realistic collision. Now the reason I included that info about P and K is so that if you want non-head on collisions or different masses, you should be able to incorporate that. If the masses aren't the same, the velocity's won't simply change magnitudes and directions. There will be a lot more math involved. I hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top