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.
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
- 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.
- 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).
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
- Implemente as funções collisionPoint(Point p) e collisionCircle(Circle c) definidas no código acima.
- Faça um programa que tenha duas esferas em movimento. Observe as seguintes características:
- 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;
- 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
(...)