void Form1_KeyDown(object sender, KeyEventArgs e) { int i = 14; Vetor velocidade = new Vetor(); switch (e.KeyValue) { case 32: //Espaço break; case 38: // Cima velocidade = new Vetor(0, -i); break; case 40: // Baixo velocidade = new Vetor(0, i); break; case 39: // Direita velocidade = new Vetor(i, 0); break; case 37: // Esquerda velocidade = new Vetor(-i, 0); break; } Vetor jogadorTransladacao = velocidade; foreach (Poligono poligono in poligonos) { // Ignora o jogador no tratamento if (poligono == jogador) { continue; } // Testa a colisão com os polígonos ColisaoPoligonoResultado r = ColisaoPoligono(jogador, poligono, velocidade); if (r.Interceptar) { jogadorTransladacao = velocidade + r.TranslacaoMinimaVetor; break; } } jogador.Posicao(jogadorTransladacao); }
// Verifique se o polígono A vai colidir com o polígono B na velocidade dada public ColisaoPoligonoResultado ColisaoPoligono(Poligono poligonoA, Poligono poligonoB, Vetor velocidade) { ColisaoPoligonoResultado resultado = new ColisaoPoligonoResultado(); resultado.Intersecao = true; resultado.Interceptar = true; int arestaCountA = poligonoA.Arestas.Count; int arestaCountB = poligonoB.Arestas.Count; float minIntervalDistance = float.PositiveInfinity; Vetor EixoTranslacao = new Vetor(); Vetor aresta; // Loop através de todas as bordas de ambos os polígonos for (int indiceAresta = 0; indiceAresta < arestaCountA + arestaCountB; indiceAresta++) { if (indiceAresta < arestaCountA) { aresta = poligonoA.Arestas[indiceAresta]; } else { aresta = poligonoB.Arestas[indiceAresta - arestaCountA]; } // ===== 1. Descobrir se os polígonos estão se cruzando atualmente ===== // Encontre o eixo perpendicular à borda atual Vetor eixo = new Vetor(-aresta.Y, aresta.X); eixo.Normalizar(); // Encontre a projeção do polígono no eixo atual float minA = 0; float minB = 0; float maxA = 0; float maxB = 0; ProjecaoPoligono(eixo, poligonoA, ref minA, ref maxA); ProjecaoPoligono(eixo, poligonoB, ref minB, ref maxB); // Verifique se as projeções de polígono estão se cruzando atualmente if (DistanciaDoIntervalo(minA, maxA, minB, maxB) > 0) { resultado.Intersecao = false; } // ===== 2. Agora, encontre os polígonos que irão se *cruzar* ===== // Projetar a velocidade no eixo atual float velocidadeProjecao = eixo.ProdutoPontual(velocidade); // Obter a projeção do polígono A durante o movimento if (velocidadeProjecao < 0) { minA += velocidadeProjecao; } else { maxA += velocidadeProjecao; } // Faça o mesmo teste acima para a nova projeção float distanciaDoIntervalo = DistanciaDoIntervalo(minA, maxA, minB, maxB); if (distanciaDoIntervalo > 0) { resultado.Interceptar = false; } // Se os polígonos não estiverem se cruzando e não se cruzarem, saia do loop if (!resultado.Intersecao && !resultado.Interceptar) { break; } // Verifique se a distância atual do intervalo é a mínima. // Em caso afirmativo, armazene a distância do intervalo e a distância atual. // Isso será usado para calcular o vetor de transladação mínima distanciaDoIntervalo = Math.Abs(distanciaDoIntervalo); if (distanciaDoIntervalo < minIntervalDistance) { minIntervalDistance = distanciaDoIntervalo; EixoTranslacao = eixo; Vetor d = poligonoA.Centro - poligonoB.Centro; if (d.ProdutoPontual(EixoTranslacao) < 0) { EixoTranslacao = -EixoTranslacao; } } } // O vetor de transladação mínimo pode ser usado para pressionar os polígonos. // Primeiro move os polígonos pela sua velocidade e, em seguida, move PoligonoA por TransladacaoMinimaVetor. if (resultado.Interceptar) { resultado.TranslacaoMinimaVetor = EixoTranslacao * minIntervalDistance; } return(resultado); }