How to do collision in game with Java 2D platform?

3

I'm trying for several days to do a collision method that returns me or tell me the sides of a rectangle that are being bumped. I have already used the intersects method but this only returns me that this is having the collision in general, I need to differentiate the parts that are being collided.

In other words I have a megaman game, I have gravity worked as follows:

  • if gravity is < that 0 is jumping
  • if gravity is > which is then falling

The idea is to make when my doll is colliding with the top of a rectangle gravity stops, and when it is colliding with the side of the rectangle gravity does not stop, but it prevents it from invading the rectangle. And for this reason that collisions I need to know which parts are being collided .

    
asked by anonymous 11.06.2014 / 18:36

2 answers

4

Source: link

Pixel collision

If you need to perform a perfect detection, you can do pixel-level detection. It is important to keep in mind, as you will see, that this type of procedure, although effective, is extremely costly in terms of processing. Based on the pixels in which the overlap is detected, you can tell which side of a rectangle the collision occurred.

The main point to begin defining a pixel collision detection function (or method) is to understand that bitmaps images are stored as repeating whole numbers along the bitmap. Each color is associated with a number. In general, the transparent color is associated with the number 0 (zero).

To optimize the process, we first define whether there is a collision between the object's surrounding polygons (assuming rectangles). In case there is no collision between the surrounding polygons, it is impossible to collide between objects. On the other hand, if there is a collision between the surrounding polygons then there is the possibility that there was a collision between objects.

Notice that in the first case our work is finished. In the second case, we have to define what was the collision area (which in the case of surrounding rectangles gives us a new rectangle). We will call this overlapping rectangle rectangle. It is the area where the two rectangles of objects overlapped.

Now what we have to do is to traverse this area of the overlapping rectangle in the two images (pixel by pixel) and determine if in both images there is a same pixel of the overlapping rectangle where the two images have a non-transparent color. If both object images have non-transparent pixels in the same position within the overlapping rectangle then there was actually collision.

The pseudo-code below shows this procedure:

/*retorna 0 se não houve colisão, ou 1 se houve colisão*/
int Função ColisaoPorPixel(objeto1, objeto2)
{

      //Define os pontos corners dos objetos
        left1 = objeto1.x;
      left2 = objeto2.x;
      right1 = objeto1.x + object1.largura;
      right2 = objeto2.x + object2.largura;
      top1 = objeto1.y;
      top2 = objeto2.y;
      bottom1 = objeto1.y + object1.altura;
      bottom2 = objeto2.y + object2.altura;

/*Teste de rejeição para colisão de polígonos circundantes*/
      if (bottom1 < top2) returna(0);
      if (top1 > bottom2) returna(0);

      if (right1 < left2) returna(0);
      if (left1 > right2) returna(0);


/*Se chegamos aqui é porque pode haver colisão, descubra o retângulo de sobreposição*/
      if (bottom1 > bottom2) 
            over_bottom = bottom2;
      else 
            over_bottom = bottom1;

      if (top1 < top2) 
            over_top = top2;
      else 
            over_top = top1;

      if (right1 > right2) 
            over_right = right2;
      else 
            over_right = right1;

      if (left1 < left2) 
            over_left = left2;
      else 
            over_left = left1;


    // Agora situa as áreas de comparação nos dois objetos
    i = ((over_top – objeto1.y) * objeto1.largura) + over_left;
    pixel1 = objeto1.frames[objeto1.curr_frame] + i;

    j = ((over_top - objeto2.y) * objeto2.largura) + over_left;
    pixel2 = objeto2.frames[objeto2.curr_frame] + j;

/* Agora começa a varrer todos o retângulo de sobreposição, testando se o correspondente pixel de 
     cada bitmap de cada objeto,para ver se ambos são  
     diferentes de zero
     */

    for (i=0; i < over_height; i++) 
    {
        for (j=0; j < over_width; j++) 
        {
            if (objeto1[pixel1].cor > 0) && (objeto2[pixel2].cor > 0) 
            {
                  //houve colisão
                  return(1);
            }
            pixel1++;
            pixel2++;
        }
        pixel1 += (objeto1.largura - over_width);
        pixel2 += (objeto2.largura - over_width);
    }

/* Pior caso do algoritmo!  Varremos o retângulo de sobreposição e não encontramos nenhuma colisão*/ 

    return(0);
};

As stated above, it is important to understand that this algorithm, while completely effective, is very costly. For many objects moving on the screen at the same time, for which you have to test collision, this procedure can simply make your game get almost so slow.

Considering the shape of the objects, their sizes and how realistic the game needs to be. We can think of ways to combine the collision detection techniques learned to form a treatment that although it is more complex, since dealing with several cases, can also be quite efficient: the hierarchical collision detection.

    
11.06.2014 / 19:03
0

Dude, when are you on top of a gravity box for? Not! So you do not have to undo gravity ... simply make sure the character collides with the box and does not invade it. Let gravity keep acting. You will void gravity through the normal force of the box.

    
07.06.2015 / 20:58