1
\$\begingroup\$

First things first. I am using C# with XNA. My game is top-down and the player can shoot bullets. I've managed to get the bullets to ricochet correctly off horizontal walls. Yet, despite using similar methods (e.g. https://stackoverflow.com/questions/3203952/mirroring-an-angle) and reading other answered questions about this subject I have not been able to get the bullets to ricochet off a vertical wall correctly. Any method I've tried has failed and sometimes made ricocheting off a horizontal wall buggy.

Here is the collision code that calls the ricochet method:

//Loop through returned tile rectangles from quad tree to test for wall collision. If a collision occurs perform collision logic.
for (int r = 0; r < returnObjects.Count; r++)
    if (Bullets[i].BoundingRectangle.Intersects(returnObjects[r]))
        Bullets[i].doCollision(returnObjects[r]);

Now here is the code for the doCollision method.

    public void doCollision(Rectangle surface)
    {
        if (Ricochet) doRicochet(surface);
        else Trash = true;
    }

Finally, here is the code for the doRicochet method.

    public void doRicochet(Rectangle surface)
    {
        if (Position.X > surface.Left && Position.X < surface.Right)
        {
            //Mirror the bullet's angle.
            Rotation = -1 * Rotation;
            //Moves the bullet in the direction of its rotation by given amount.
            moveFaceDirection(Sprite.Width * BulletScale.X);
        }
        else if (Position.Y > surface.Top && Position.Y < surface.Bottom)
        {
        }
    }

Since I am only dealing with vertical and horizontal walls at the moment, the if statements simply determine if the object is colliding from the right or left, or from the top or bottom. If the object's X position is within the boundaries of the tile's X boundaries (left and right sides), it must be colliding from the top, and vice verse. As you can see, the else if statement is empty and is where the correct code needs to go.

\$\endgroup\$
1

1 Answer 1

2
\$\begingroup\$

It looks like your code to mirror the bullet's angle just flips the sign of the angle. This works great for reflecting an angle about the x-axis. 45 degrees becomes -45 degrees, etc.

Now imagine reflecting off a wall that itself has an angle of 90 degrees. In this case, 85 degrees is reflected to 95 degrees; 45 degrees becomes 135 degrees, etc. Basically you need to transform the bullet angle to be relative to the wall before flipping.

Instead of just doing rotation = -rotation, I would suggest a function for reflecting an angle about another angle A: rotation = A - (rotation-A). (notice what happens when A == 0)

Now find the angle that your wall is at, and use that as A. You could use an if-else statement to choose between 0 and 90; or you could calculate the angle from the two endpoints of your wall, and then you could handle walls at arbitrary angles just as well as vertical or horizontal walls.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the reply, it works now! The only problem is my sub-par collision system so inevitably the bullets wig out sometimes. \$\endgroup\$
    – Bagofsheep
    Commented Apr 18, 2014 at 12:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .