AllyOmega
AllyOmega

Reputation: 45

How do I implement simple 2d ball collision?

I've been working on this project for a class, and I just wanted some advice on how to move forward. Basically, my project is that on button click a ball is drawn on the form (each button click adds an extra ball). This ball is supposed to bounce off of the edges of the form and also collide with other balls.

I've gotten everything else done; right now I'm trying to get the ball collision working. It doesn't have to be physically accurate or anything; Right now I'm just having trouble getting them to recognize each other. Here's my code (apologies in advance if the code is sloppy. I've been really scatterbrained lately with all of my classes and I've barely been able to squeeze time in to get this thing done, so my thought process may be way off base):

    namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    {

            int i = 0;
            int X;
            int Y;
            bool bounceX;
            bool bounceY;
            System.Drawing.Graphics g;
            List<Ball> ball = new List<Ball>();
            System.Timers.Timer timer = new System.Timers.Timer(16);

            public Form1()
            {
                InitializeComponent();
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                g = this.CreateGraphics();
                timer.Elapsed += new ElapsedEventHandler(timer_Tick);

            }

            private void button1_Click(object sender, EventArgs e)
            {
                Ball curball = new Ball();
                ball.Add(curball);

                ball[i].defineball(X, Y, bounceX, bounceY);
                Random r = new Random();
                X = r.Next(1, this.Width - 1);
                Y = r.Next(1, this.Height - 1);
                bounceX = r.Next(0, 2) > 0;
                bounceY = r.Next(0, 2) > 0;
                timer.Enabled = true;
                i++;
            }
            private void timer_Tick(object source, ElapsedEventArgs e)
            {
                   g.Clear(this.BackColor);
                   curball.newball(g);
                }
            }
        }
    }

   class Ball : Form1
    {
        int radius = 25;
        int X;
        int Y;
        bool bounceX;
        bool bounceY;
        public bool detect = false;
        public void defineball(int X, int Y, bool bounceX, bool bounceY)
        {   
            this.X = X;
            this.Y = Y;
            this.bounceX = bounceX;
            this.bounceY = bounceY;
    }
        public void newball(System.Drawing.Graphics g)
        {
            if (detect != true)
            {
                if (X >= this.Width - 50)
                {
                    bounceX = true;
                }
                else if (X <= 25)
                {
                    bounceX = false;
                }

                if (Y >= this.Height - 50)
                {
                    bounceY = true;
                }
                else if (Y <= 25)
                {
                    bounceY = false;
                }
            }

            if (bounceX == false)
            {
                X++;
            }
            else if (bounceX == true)
            {
                X--;
            }

            if (bounceY == false)
            {
                Y++;
            }
            else if (bounceY == true)
            {
                Y--;
            }
            Pen clsPen = Pens.Black;
            Color color = Color.Black;
            SolidBrush brush = new SolidBrush(color);
            g.DrawEllipse(clsPen, X - 20, Y - 30, 50, 50);
            g.FillEllipse(brush, X - 20, Y - 30, 50, 50);
            this.detect = false;
        }
    }
}

This is the direction that I was sort of going in:

 foreach (var curball in ball)
                {

                  // how do i get these stupid balls to detect each other? 
                  // research the math of circles and such

                    foreach (var checkball in ball)
                    {
                            if (curball.X - checkball.X <= 25
                                && curball.X - checkball.X >= -25
                                && curball.Y - checkball.Y <= 25
                                && curball.Y - checkball.Y >= -25
                                && curball.detect != true)
                            {
                                //bool tempX = curball.bounceX;
                                //bool tempY = curball.bounceY;
                                //curball.bounceX = checkball.bounceX;
                                //curball.bounceY = checkball.bounceY;
                                checkball.bounceX = !checkball.bounceX;
                                checkball.bounceY = !checkball.bounceX;
                                checkball.detect = true;
                                curball.detect = true;

                            }
                    }

But I haven't really figured out how to avoid the ball checking itself and "flipping" the detect switch. I also don't think my "detect switch" is working correctly in the first place! Can anyone lend a helping hand?

Upvotes: 1

Views: 2234

Answers (1)

JimmyB
JimmyB

Reputation: 12640

Two circles are tangential to each other when the distance of their centers is the sum of their radii.

Calculate the distances between the centers of the balls (3D) or circles (2D). If the distance between two centers is equal to or less than the sum of both radii, the two circles are colliding and need to bounce off each other.

d^2 = (x2-x1)^2 + (y2-y1)^2

if (r1+r2)^2 <= d^2 you have a collision.

Upvotes: 2

Related Questions