Colisões

De Aulas
(Redirecionado de Aula 9: Colisões)

Links Relacionados: Matemática e Física para Jogos, Jogos Digitais

Bounding Box

Este é um dos algoritmos mais rápidos de detecção de colisões. Contudo, ele pode não ser muito eficiente para diversos tipos de aplicações. A base do algoritmo é definir retângulos nos objetos e testando se um ponto está dentro deste retângulo.

A imagem abaixo representa a colisão entre dois retângulos. No caso, É verificado que o ponto inferior direito do retângulo A está na área interna do retângulo B.

Boundingbox 01.png

O código a seguir representa a implementação da colisão de um ponto com um retângulo:

 1class Point {
 2public:
 3    float x;
 4    float y;
 5    Point(float _x, float _y) : x(_x), y(_y) {}
 6};
 7
 8class Rectangle {
 9public:
10	Point p1;
11	Point p2;
12	Rectangle(float x1, float y1, float x2, float y2) : p1(x1, y1),  p2(x2, y2) {}
13	bool collision(Point p);
14};
15
16bool Rectangle::collision(Point p) {
17	if ((p.x > p1.x) && (p.x < p2.x) && (p.y > p1.y) && (p.y < p2.y)) {
18		return true;
19	}
20	return false;
21}

Exercícios

  1. Imagine um jogo de luta (estilo Street Fighter), como deveríamos fazer a detecção de colisão entre os personagens de forma eficiente, considerando o braço para soco e defesa e para a perna, chute.
  2. Implemente um programa que faz a detecção de colisão entre dois personagens com base na resposta da questão anterior.

Colisão entre Círculos

No caso do círculo, o bounding box não seria muito eficaz. Dessa forma, um outro método é utilizado para a detecção de colisão. Uma forma é o cálculo da distância de um ponto até o centro do círculo, descontando o raio do mesmo. No caso de dois círculos, haveria colisão caso a distância menos a soma dos raios fosse menor ou igual a zero.

Para calcular a distância entre um círculo e um ponto, fazemos a distância do ponto até o ponto central do círculo diminuindo o raio.

Primeiro temos que a distância entre dois pontos é:

distancia = raiz( (x2 - x1)2 + (y2 - y1)2)

logo:

colisaoPontoCirculo = distancia - raio

Da mesma forma, teríamos que a distância entre dois círculos seria:

colisaoEntreCirculos = distancia - raioCirculo1 - raioCirculo2

A figura abaixo representa a detecção de colisão entre um ponto e um círculo (esquerda) e a detecção de colisão entre dois círculos (direita).

Colisao circulos01.png

Segue abaixo o código para definição do nosso círculo. Observe que a classe Point já foi definida na atividade anterior.

1class Circle {
2public:
3    Point center; // Point ja esta definido no exemplo do retangulo.
4    float radius;
5    Circle(float _x, float _y, float _r) : center(_x, _y), radius(_r) {}
6    bool collisionPoint(Point p);
7    bool collisionCircle(Circle c);
8};

Exercícios

  1. Implemente as funções collisionPoint(Point p) e collisionCircle(Circle c) definidas no código acima.
  2. Faça um programa que tenha duas esferas em movimento. Observe as seguintes características:
    1. Quando uma esfera toca um canto da tela, ela retorna com a mesma força para o lado oposto, tanto no eixo x como no eixo y;
    2. Quando as esferas se chocam, elas também retornam com a mesma força para o lado oposto. Considere a colisão entre esferas.

Colisão por Pixel Perfect

(...)

Colisão entre Polígonos

(...)