Collision with a growing/shrinking circle

Started by
2 comments, last by dragonbladex 16 years, 1 month ago
Hello all. I am currently programming a game where an object, a ball spawns at a random location and moves in a random direction and upon contact with a stationary circle, this circle will grow a little. There is also another circle in the same area, except this one shrinks upon collision. I am using a boolean function for the collision detection and am getting the coordinates center of the ball and circles to determine their distance from each other for collision detection, the coding is as below.
private bool obstacleCollisionDetection()
        {
            Point ballCenter = new Point(this.ballBoundingBox.X + ballRadius,
                this.ballBoundingBox.Y + ballRadius);

            Point sphereCenter1 = new Point(this.sphereBoundingBox1.X + sphereRadius1, 
                this.sphereBoundingBox1.Y + sphereRadius1); // create a coordinate center for scoring sphere 1 for collision detection 

            Point sphereCenter2 = new Point(this.sphereBoundingBox2.X + sphereRadius2,
                this.sphereBoundingBox2.Y + sphereRadius2); // create a coordinate center for scoring sphere 2 for collision detection

            // Note: There is a logic problem with this growing sphere, the shrinking one
            // is fine.
            // If the either of the colliding object is not destroyed upon collision, the
            // moving ball will get stuck within the sphere and will loop, infinitely
            // increasing its size. This should not be a problem for us as one of our balls is
            // destroyed upon contact but just to highlight the issue.
            Vector distanceVector2 = sphereCenter1 - ballCenter; // checks for collision for scoring sphere 1
            if (distanceVector2.Length < (ballRadius + sphereRadius1))
            {
                this.Children.Remove(scoringSphere1); // destroy original scoring sphere
                if (sphereRadius1 <= 75) // for winning game if a target size is reached
                {
                    sphereRadius1 += 5; // increase sphere size
                }
                makeScoringSphere1(sphereRadius1); // creates a bigger scoring sphere

                distanceVector2.Normalize();
                BallDirection = 2 * Vector.Multiply(-BallDirection, distanceVector2)
                    * distanceVector2 + BallDirection;
            }

            Vector distanceVector3 = sphereCenter2 - ballCenter; // checks for collision for scoring sphere 2
            if (distanceVector3.Length < (ballRadius + sphereRadius2))
            {
                distanceVector3.Normalize();
                BallDirection = 2 * Vector.Multiply(-BallDirection, distanceVector3)
                    * distanceVector3 + BallDirection;

                this.Children.Remove(scoringSphere2); // destroy original scoring sphere
                if (sphereRadius2 >= 25) // for losing game if a target size is reached
                {
                    sphereRadius2 -= 5; // decrease sphere size
                }
                makeScoringSphere2(sphereRadius2); // creates a smaller scoring sphere
            }

            int i = 0;
            foreach (Point obstacle in obstacleCenters)
            {
                Vector distanceVector = obstacle - ballCenter;
                if (distanceVector.Length < (ballRadius + obstacleRadius))
                {
                    // look at http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=30
                    // for a proper explanation on how to calculate the new direction vector
                    distanceVector.Normalize();
                    BallDirection = 2 * Vector.Multiply(-BallDirection,distanceVector)
                        * distanceVector + BallDirection;
                    
                    // delete obstacle
                    this.obstacleCenters.RemoveAt(i);
                    Ellipse ellipseToRemove = this.obstacles;
                    this.Children.Remove(ellipseToRemove);
                    this.obstacles.Remove(ellipseToRemove);

                    // rewind and play the sound
                    mp.Position = TimeSpan.FromMilliseconds(0);
                    mp.Play();
                    return true;
                }
                i++;
            }
            return false;
        }
From what I can understand, especially so for the growing circle, is that it will trap the bouncing ball within itself and keeps growing until it reaches its maximum size. A similar problem also happens for the smaller circle, mostly when the ball 'grazes' the circle. What extra condition do I need to add to the collision to make the ball get away from the circle but maintain the growth of the circle? The only clue I have to go by at this moment is a hint from my tutor, who says "you could make sure the hit test condition is only true true if the ball hit another object in between two hits on the circle". Can anyone help me with this? [Edited by - dragonbladex on March 16, 2008 12:20:19 PM]
Advertisement
Hi,

The tags to make the little code boxes are [source][/source]. You might edit your post and enclose your code in these tags (it'll make your post easier to read).
It seems to me the easiest way to avoid the problem, is first test if the moving ball is moving towards the stationary circle.

After collision (assuming the moving ball bounces) it will be moving away.

Just take the Dot Product of the Movement Vector and the Vector from the centre of the moving ball to the centre of the stationary circle.

If that's < 0 (maybe <= 0) don't bother testing for collision, since the moving ball is moving away.

HTH
Thanks for the replies, I figured it out another way.

I used a boolean variable ballHitCircle to determine if collision detection should be done. ballHitCircle is initially false to allow collisions.

When it hits the target circle, I change the boolean to true and not allow any further collision with said circle until it hits another object. At this point I change the boolean back to false to allow collision with the circle again.

This topic is closed to new replies.

Advertisement