示例#1
0
        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);
        }
示例#2
0
        // 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);
        }