14 Replies Latest reply: Oct 30, 2009 1:29 PM by 796262 RSS

    Collision Detection Using Bounding Boxes

    843853
      Hey guys ive been trying to do collision detection for a while now but with absolutely no success my images just continue to over lap each other. Im creating a puyo game and i cant seem to be able to figure out how to draw the bounding boxes around my puyos and then check to to see if there is a collision and have them stop. If someone could explain how to implement the bounding box method id really appreciate it. If you need to see my code let me know.
        • 1. Re: Collision Detection Using Bounding Boxes
          gimbal2
          you don't draw a bounding box. A "bounding box" in Java terms can be simply implemented using the standard Rectangle class. A rectangle has four properties: an X,Y position and a width,height. To make the rectangle overlap your puyo, give it the same X,Y position (pixel location in the panel you are painting) and the width,height should be equal to the puyo image you are using.

          Now to check if two rectangles overlap, simply use its intersects method.
          • 2. Re: Collision Detection Using Bounding Boxes
            843853
            Hey gimbal2,

            Thanks for the advice i did what you said but it didn't work but i realize why. My puyo images are side by side like this [][] and when the first to connected puyos fall and touch the bottom the next two fall. I want to check if there is a collision between the two new puyos falling against the ones that have already fallen and are at the bottom. How exactly would i go about doing this using "bounding boxes" any advice? Here is what i have so far if you need to see the code for my entire class please let me know. The code i have here only checks if there is a collision between the two connected puyos which doesn't work since they are already connected. I could use some advice on how to check for collision between two different sets of connected puyo images. Once again thanks. If this makes absolutely no sense which it probably does please let me know.
             boolean collidesWith(){
                               r1 = new Rectangle(current[0].x,current[0].y,image_width, image_height);
                            r2 = new Rectangle(current[1].x,current[1].y,image_width, image_height);
                            if (r1.intersects(r2)){
                                 
                                 current[0].y = 0;
                                 current[1].y = 0;
                            }
                         return true;
                         }  
            Edited by: Riz01 on Oct 28, 2009 10:34 AM
            • 3. Re: Collision Detection Using Bounding Boxes
              796262
              Your code checks for a collision, and if there is one, sets both y values to 0 (the top of the screen). Is that what you want to do?

              Like has been requested from you before, you should strongly consider posting an SSCCE and specifically spelling out exactly what you want to be happening versus what is happening.
              • 4. Re: Collision Detection Using Bounding Boxes
                843853
                Sorry for the poor explanation, every time i run my program the puyo images simply overlap each other there is no collision the code that i posted has no effect what so ever on the state of my game/program. What i want to do is check for a collision between two different sets of connected puyos. so something like this

                [New Puyo 1][New Puyo 2] COLLISION!
                [Puyo 1] [Puyo 2]

                How would i go about checking to see if there is a collision between two different sets of puyos and have them stop on top of each other. Essentially its just like it would be in tetris, a block comes down stops and then another block comes down and stops on top of that one and so on and so forth hope this clarifies my problem better.

                Edited by: Riz01 on Oct 28, 2009 11:40 AM

                Edited by: Riz01 on Oct 28, 2009 12:59 PM

                Edited by: Riz01 on Oct 28, 2009 1:09 PM
                • 5. Re: Collision Detection Using Bounding Boxes
                  796262
                  Riz01 wrote:
                  Sorry for the poor explanation, every time i run my program the puyo images simply overlap each other there is no collision the code that i posted has no effect what so ever on the state of my game/program.
                  That's why an SSCCE would be so extremely helpful here. We can't see how you're using the code you posted. And posting all of your code will just be confusing, so nobody will want to read through all the extra game logic and stuff. What you want to post is just the smallest program possible that shows two shapes using your collision detection code.
                  What i want to do is check for a collision between two different sets of connected puyos. so something like this

                  [New Puyo 1][New Puyo 2] COLLISION!
                  [Puyo 1] [Puyo 2]
                  I have no idea what a "puyo" is. What do you mean that sets of puyos can be connected? Again, an SSCCE would help demonstrate what you're trying to do...
                  How would i go about checking to see if there is a collision between two different sets of puyos and have them stop on top of each other.
                  Basically the logic you'll want to do is something like this:
                  for each shape:
                     calculate the position that shape will be in after the next time it moves
                     if that position is overlapping another shape
                        set the position of the moving shape so that it is just touching the other shape
                  There are other things to consider, but that's the gist. Again, an SSCCE would be extremely helpful here, as we'd then have something to go off of.
                  Essentially its just like it would be in tetris, a block comes down stops and then another block comes down and stops on top of that one and so on and so forth hope this clarifies my problem better.
                  It does, but not as much as an SSCCE would clarify.
                  • 6. Re: Collision Detection Using Bounding Boxes
                    843853
                    Not sure if this totally follows SSCCE since this cant be run but here is the code where i attempt what iam
                    describing
                     //Here is where i create my array
                    puyolist = new Puyo[board_width][board_height];
                             
                    //here i store the images in my array and set the color to random and their location on screen
                             current = new Puyo[2];
                             current[0] = new Puyo(myRand.nextInt(4), (board_width * image_width /3), 0);
                             current[1] = new Puyo(myRand.nextInt(4), (board_width * image_width /3)+image_width, 0);
                    
                    public void paintComponent(Graphics g){
                         super.paintComponent(g);  
                         /*Here i save the locations of images on the board and then when a puyo is dropped and touches the bottom
                              of the JFrame it saves its location in other words it keeps the images from dissapearing and the drops
                              another set of puyos by.*/
                             for(int i = 0; i < board_width; i++){
                                  for(int j = 0; j < board_height; j++){
                                      if(puyolist[i][j] != null)
                                       g.drawImage(images[puyolist[i][j].color],puyolist[i][j].x,puyolist[i][j].y,this);
                                  
                                    /*Here is where i attempt to create bounding boxes to encapsulate my images but i get no collision
                                     i think that this is actually checking for a collision between the two connected images but that
                                     will never happen since they are connected to each other.  What i want to do is check if there is a collision
                                     between to *different* sets of connected images.*/
                                       //this checks if image1 collides with image 2 but image 1 and image 2 are connected to each other
                                      //side by side
                                      r1 = new Rectangle(current[0].x,current[0].y,image_width, image_height);
                                     r2 = new Rectangle(current[1].x,current[1].y,image_width, image_height);
                                       (r1.intersects(r2)){
                                      }
                                   }
                                //Here i draw the two connected puyos to the screen
                            g.drawImage(images[current[0].color],current[0].x,current[0].y,this);
                            g.drawImage(images[current[1].color],current[1].x,current[1].y,this);
                          }
                    Edited by: Riz01 on Oct 29, 2009 12:25 PM

                    Edited by: Riz01 on Oct 29, 2009 12:26 PM

                    Edited by: Riz01 on Oct 29, 2009 12:27 PM

                    Edited by: Riz01 on Oct 29, 2009 12:29 PM

                    Edited by: Riz01 on Oct 29, 2009 12:33 PM

                    Edited by: Riz01 on Oct 29, 2009 12:36 PM

                    Edited by: Riz01 on Oct 29, 2009 12:39 PM
                    • 7. Re: Collision Detection Using Bounding Boxes
                      796262
                      Run this, see whether that's what you're talking about, then ask questions about anything you don't understand:
                      import javax.swing.*;
                      import java.awt.*;
                      
                      public class PuyoTest extends JPanel{
                              
                          Rectangle fallingRectangle = new Rectangle(225, 0, 50, 50);
                          Rectangle floorRectangle = new Rectangle(0, 300, 500, 50);
                              
                          public PuyoTest() {
                               
                               JFrame frame = new JFrame("Testing Rectangles");
                               frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                               frame.setSize(500, 500);
                               frame.add(this);
                               frame.setVisible(true);
                               
                               while(true){
                                    doGameLogic();
                               }
                          }
                          
                          
                          public void doGameLogic(){
                               
                               fallingRectangle.translate(0, 1);
                               
                               if(fallingRectangle.getY() > floorRectangle.getY() - fallingRectangle.getHeight()){
                                    fallingRectangle.setLocation((int)fallingRectangle.getX(), (int)(floorRectangle.getY() - fallingRectangle.getHeight()));
                               }
                               
                               try{
                                    Thread.sleep(50);
                               }
                               catch(Exception e){
                                    System.out.println("Trouble sleeping.");
                               }
                               
                               repaint();
                          }
                          
                          public void paintComponent(Graphics g){
                                   super.paintComponent(g);  
                                    
                                   g.drawRect((int)fallingRectangle.getX(), (int)fallingRectangle.getY(), (int)fallingRectangle.getWidth(), (int)fallingRectangle.getHeight());
                                   g.drawRect((int)floorRectangle.getX(), (int)floorRectangle.getY(), (int)floorRectangle.getWidth(), (int)floorRectangle.getHeight());     
                          }
                           
                          public static void main(String[] args) {
                              new PuyoTest();
                          }
                      }
                      • 8. Re: Collision Detection Using Bounding Boxes
                        843853
                        Hey thanks a lot i really appreciate all your help thanks for taking the time out and making this example i really appreciate it anyway i was able to re work your example and im pretty sure now everyone will understand what it is im trying to do.

                        The floor rectangle that is across the frame is the border line. The first two connected rectangles fall fast, and then stop when they hit the floor rectangle at the same time i have another two connected rectangles falling but at a slower rate to kinda demonstrate how in my game when the first to puyos hit the border line the next two fall.

                        Now when the slower falling connected rectangles are about to come into contact with the connected rectangles that are already on the floor rectangle they do not stop on top they simply just continue to fall and overlap them. This is whats happening in my game the first puyos fall then stop and then when the next two puyos fall they simply overlap the first two and so on and so forth. How would i detect if their is a collision between them?

                        I think that perhaps the code i submitted which tests for collision is actually checking to see if there is a collision between the two connected puyos or in the case of this example the two rectangles but that cant happen since they are connected.
                        So how i would check for a collision between the first pair of connected rectangles and the second pair of rectangles that fall after? I hope this explains everything better thanks again.
                        import javax.swing.*;
                        import java.awt.*;
                         
                        public class PuyoTest extends JPanel{
                                
                            Rectangle fallingRectangle = new Rectangle(225, 0, 50, 50);
                            Rectangle fallingRectangle2 = new Rectangle(275, 0, 50, 50);
                            Rectangle fallingRectangle3 = new Rectangle(225, 0, 50, 50);
                            Rectangle fallingRectangle4 = new Rectangle(275, 0, 50, 50);
                            Rectangle floorRectangle = new Rectangle(0, 300, 500, 50);
                                
                            public PuyoTest() {
                                 
                                 JFrame frame = new JFrame("Testing Rectangles");
                                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                                 frame.setSize(500, 500);
                                 frame.add(this);
                                 frame.setVisible(true);
                                 
                                 while(true){
                                      doGameLogic();
                                 }
                            }
                            
                            
                        
                            
                            public void doGameLogic(){
                                 
                                 fallingRectangle.translate(0, 5);
                                 fallingRectangle2.translate(0, 5);
                                 fallingRectangle3.translate(0, 1);
                                 fallingRectangle4.translate(0, 1);
                                 
                                 if(fallingRectangle.getY() > floorRectangle.getY() - fallingRectangle.getHeight()){
                                      fallingRectangle.setLocation((int)fallingRectangle.getX(), (int)(floorRectangle.getY() - fallingRectangle.getHeight()));
                                      fallingRectangle2.setLocation((int)fallingRectangle2.getX(), (int)(floorRectangle.getY() - fallingRectangle.getHeight()));
                                 }
                                 if(fallingRectangle3.getY() > floorRectangle.getY() - fallingRectangle.getHeight()){
                                      fallingRectangle3.setLocation((int)fallingRectangle3.getX(), (int)(floorRectangle.getY() - fallingRectangle.getHeight()));
                                      fallingRectangle4.setLocation((int)fallingRectangle4.getX(), (int)(floorRectangle.getY() - fallingRectangle.getHeight()));
                                 }
                                 
                                 try{
                                      Thread.sleep(50);
                                 }
                                 catch(Exception e){
                                      System.out.println("Trouble sleeping.");
                                 }
                                 
                                 repaint();
                            }
                          
                        
                        
                            public void paintComponent(Graphics g){
                                     super.paintComponent(g);  
                                      
                                     g.drawRect((int)fallingRectangle.getX(), (int)fallingRectangle.getY(), (int)fallingRectangle.getWidth(), (int)fallingRectangle.getHeight());
                                     g.drawRect((int)fallingRectangle2.getX(), (int)fallingRectangle2.getY(), (int)fallingRectangle2.getWidth(), (int)fallingRectangle2.getHeight());
                                      g.drawRect((int)fallingRectangle3.getX(), (int)fallingRectangle3.getY(), (int)fallingRectangle3.getWidth(), (int)fallingRectangle3.getHeight());
                                     g.drawRect((int)fallingRectangle4.getX(), (int)fallingRectangle4.getY(), (int)fallingRectangle4.getWidth(), (int)fallingRectangle4.getHeight());
                                     g.drawRect((int)floorRectangle.getX(), (int)floorRectangle.getY(), (int)floorRectangle.getWidth(), (int)floorRectangle.getHeight());     
                            }
                             
                            public static void main(String[] args) {
                                new PuyoTest();
                            }
                        }
                        Edited by: Riz01 on Oct 29, 2009 7:55 PM

                        Edited by: Riz01 on Oct 29, 2009 7:55 PM

                        Edited by: Riz01 on Oct 29, 2009 8:39 PM
                        • 9. Re: Collision Detection Using Bounding Boxes
                          796262
                          Can two groups of these "puyos" be falling at the same time? What I mean is, like in your example, can you have a group of connected "puyos" collide in mid-air? Or are you only worried about collisions with already stopped "puyos"?

                          Either way, you have to check against every other shape you want to detect collision with. You have to use the same logic we use here (plus some more if you want to check for collisions on the left and right sides, etc). Instead of only checking against the ground, you have to check against every other shape. A List of already fallen (or currently falling, depending on how this game is supposed to work) "puyos" would be useful for that.
                          • 10. Re: Collision Detection Using Bounding Boxes
                            843853
                            Hey thanks a lot for the reply, only one group of puyos can fall at a time there can be no collision in mid air im only worried about collision with already stopped puyos. Ive already implemented bounds checking with the left and right sides of my J Frame and currently have an array which stores the a list of currently fallen puyos and saves them. My problem is exactly how do i go about checking to see if there is a collision against every other puyo in my array i really have no ideas on how to go about that. If you can suggest anything or explain the logic behind it id really appreciate it.
                            • 11. Re: Collision Detection Using Bounding Boxes
                              796262
                              Riz01 wrote:
                              Hey thanks a lot for the reply, only one group of puyos can fall at a time there can be no collision in mid air im only worried about collision with already stopped puyos. Ive already implemented bounds checking with the left and right sides of my J Frame and currently have an array which stores the a list of currently fallen puyos and saves them. My problem is exactly how do i go about checking to see if there is a collision against every other puyo in my array i really have no ideas on how to go about that. If you can suggest anything or explain the logic behind it id really appreciate it.
                              You could add all of the "already fallen" puyos to a List. Then you check against that List (and the ground rectangle) when a new set of "puyos" is falling. When the falling puyos hit either the ground or another puyo, set its position appropriately, stop moving it, and add it to the List of fallen "puyos".

                              As for the left and right collision: how can you have implemented that but not know how to implement collision between puyos? It's the same concept, just applied to a different Object. Anyway, what I meant by left and right collision was more along this line: what if a falling "puyo" is next to a stack of already fallen "puyos" and tries to move through the stack going left-to-right?
                              • 12. Re: Collision Detection Using Bounding Boxes
                                843853
                                Oh i see what i meant by left and right was just keeping the puyos within the frame i hadn't even thought about seeing if a set of puyos touch another set puyos while going left and right through the stack. And i actually already have all the fallen puyos added to a list. Are you saying i should create another list and check that list against the current list that i have?
                                • 13. Re: Collision Detection Using Bounding Boxes
                                  796262
                                  Riz01 wrote:
                                  Oh i see what i meant by left and right was just keeping the puyos within the frame i hadn't even thought about seeing if a set of puyos touch another set puyos while going left and right through the stack. And i actually already have all the fallen puyos added to a list. Are you saying i should create another list and check that list against the current list that i have?
                                  No. If they are all already in a List, just use that one. If I were you though, I'd get something working in the SSCCE I made before you attempt to put it in your program. That way you can work on the bare minimum without getting interference from any other game logic you have going on, and we can work off the same code if you have any questions. It's easier to go from an SSCCE to your program than it is to go the other way around.
                                  • 14. Re: Collision Detection Using Bounding Boxes
                                    796262
                                    I'm about to head out for the weekend, so good luck with everything. I look forward to seeing where you go from here.

                                    Just to show you (and because it's a Friday afternoon) that by using the logic in my SSCCE, a little creativity, and not too much extra code, you can create some pretty neat effects, I added a bit of (mostly useless to your actual program) code to play around with. Here's an almost realistic-looking bouncing ball:
                                    import javax.swing.*;
                                    import java.awt.*;
                                     
                                    public class PuyoTest extends JPanel{
                                            
                                        Rectangle fallingRectangle = new Rectangle(225, 0, 20, 20);
                                        Rectangle floorRectangle = new Rectangle(0, 300, 500, 10);
                                        int ySpeed = 0;
                                            
                                        public PuyoTest() {
                                             
                                             JFrame frame = new JFrame("Testing Rectangles");
                                             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                                             frame.setSize(500, 500);
                                             
                                             setBackground(Color.BLACK);
                                             
                                             frame.add(this);
                                             frame.setVisible(true);
                                             
                                             boolean keepGoing = true;
                                             while(keepGoing){
                                                  keepGoing = doGameLogic();
                                             }
                                             System.out.println("stopped.");
                                        }
                                        
                                        
                                        public boolean doGameLogic(){
                                             
                                             ySpeed ++;
                                             fallingRectangle.translate(0, ySpeed);
                                             
                                             if(fallingRectangle.getY() > floorRectangle.getY() - fallingRectangle.getHeight()){
                                                  ySpeed *= -.9;
                                                  fallingRectangle.setLocation((int)fallingRectangle.getX(), (int)(floorRectangle.getY() - fallingRectangle.getHeight()));
                                                  if(ySpeed == 0){
                                                       return false;
                                                  }
                                             }
                                             
                                             try{
                                                  Thread.sleep(50);
                                             }
                                             catch(Exception e){
                                                  System.out.println("Trouble sleeping.");
                                             }
                                             
                                             repaint();
                                             return true;
                                        }
                                        
                                        public void paintComponent(Graphics g){
                                                 super.paintComponent(g);  
                                                  g.setColor(Color.GREEN);
                                                 g.fillOval((int)fallingRectangle.getX(), (int)fallingRectangle.getY(), (int)fallingRectangle.getWidth(), (int)fallingRectangle.getHeight());
                                                 g.setColor(Color.RED);
                                                 g.fillRect((int)floorRectangle.getX(), (int)floorRectangle.getY(), (int)floorRectangle.getWidth(), (int)floorRectangle.getHeight());     
                                        }
                                         
                                        public static void main(String[] args) {
                                            new PuyoTest();
                                        }
                                    }