Detecção de colisão isométrica

11

Estou tendo alguns problemas ao tentar detectar a colisão de dois blocos isométricos.

Eu tentei plotar as linhas entre cada ponto no bloco e, em seguida, verificar se há interceptações de linhas, mas isso não funcionou (provavelmente devido à fórmula incorreta)

Depois de analisar isso por um tempo hoje, acredito que estou pensando muito nisso e deve haver uma maneira mais fácil.

Não estou procurando código, apenas alguns conselhos sobre a melhor maneira de conseguir a detecção de sobreposição

Chris Crew
fonte
4
O que exatamente você está tentando fazer? Detectar quando o mouse está sobre um bloco ou detectar se duas unidades estão sobrepostas? Se ele é o mais tarde, você deve realmente pensar sobre a separação seu "jogo" dos "gráficos"
John McDonald
Preciso fazê-lo quando o lado de um bloco isoelétrico móvel atinge um bloco não móvel, o bloco móvel para. A única coisa que estou tendo problemas é com o teste de colisão. Eu poderia usar uma caixa encadernada, mas preciso que a colisão seja precisa.
Chris Tripulação

Respostas:

23

Vou direto ao assunto e digo que não sei como resolver o problema que você descreveu na pergunta (detecção de colisão entre retângulos em forma de ladrilho iso), mas posso dizer como outras pessoas o resolveram no passado :

A maneira como é feita em outros jogos é separar o mundo do jogo do mundo da tela . Quando você está começando, é comum imaginá-los sendo a mesma coisa, mas isso leva a problemas como o que você está descrevendo.

A idéia geral é que o mundo do jogo seja completamente armazenado na memória, nos bastidores, são apenas números, referências e lógica. O fato de você estar desenhando o mundo do jogo em isométrico é irrelevante. Seu mundo de jogo não deve ter o conceito de isométrico, quadrado ou mesmo se a tela estiver sendo desenhada em 3D. Tudo isso é resolvido quando você desenha o mundo do jogo na tela (também conhecido como mundo da tela ). O mundo do jogo deve ser armazenado e mantido da maneira mais simples que faça sentido para o jogo. Em jogos isométricos, você normalmente ignora completamente o fato de ser iso e, em vez disso, armazena as posições como se estivesse usando uma grade alinhada por eixos. A maioria dos jogos terá métodos para converter coordenadas entre os dois mundos, eu chamo de meu ScreenToWorld(x, y)eWorldToScreen(x, y). A conversão geralmente é feita com a matemática Matrix, mas pode ser alcançada de outras maneiras. Você usará o ScreenToWorld ao usar o mouse e o WorldToScreen ao desenhar.

Existem várias vantagens em dividir o mundo do jogo e o mundo da tela . Uma das vantagens é que a detecção e o movimento de colisões acontecem no mundo do jogo e, portanto, geralmente são bastante diretos, porque você não está lidando com uma grade inclinada, coordenadas inclinadas ou onde a tela está etc. No seu caso , você lidaria com retângulos e quadrados alinhados ao eixo. Depois que o mundo do jogo é atualizado, você desenha uma representação do mundo do jogo na tela, palavra-chave: representação. Pode parecer contra-intuitivo no começo, mas sua tela é apenas uma representação do que está acontecendo no mundo do jogo. Isso possibilita coisas como servidores dedicados e clientes semelhantes a terminais.

O FreeCiv é realmente um ótimo exemplo de todas essas coisas. Você pode visualizar o mesmo mundo exato que qualquer um dos seguintes: Grade quadrada Norte / Sul, Isométrica ou até Hex. Cada jogo que você executa possui um servidor dedicado em execução em segundo plano, mesmo para jogos para um jogador, portanto, o cliente também é apenas uma porta de exibição, nada mais.

Resumindo: separar o mundo do jogo e a lógica do mundo da tela simplifica a lógica do jogo, reduz o acoplamento da tela do jogo e, por sua vez, torna a detecção de colisão entre blocos "iso" mais fácil de manusear e mais fácil de visualizar.

John McDonald
fonte
Obrigado pela resposta bem explicada, eu estava separando a lógica do que foi desenhado e do que está acontecendo em segundo plano, mas estava tratando tudo como uma grade inclinada.
31512 Chris
1
Para pessoas do futuro; gráficos são uma interpretação dos dados. As quatro peças principais de um jogo: lógica, dados, entrada, saída. Evite juntá-los. Além disso, excelente resposta John, +1
Aarowaim 29/04
9

A resposta de John está certa, mas tentarei explicar de uma maneira diferente:

Não há detecção de colisão isométrica.

A detecção de colisão não se importa com a aparência da sua matriz / transformação de projeção. A detecção de colisão não deve importar se você renderizar alguma coisa (afinal, objetos que estão fora da tela ainda podem colidir, certo?)

É uma pergunta mais filosófica: uma árvore que cai em uma floresta ainda colide com o chão quando não há ninguém lá?

A sabedoria convencional diria: Sim. Não importa como você olha para isso. As coisas colidem no espaço do mundo, não no espaço da visão.

MarkR
fonte
2
+1 Bem colocado. "Não há detecção de colisão isométrica"
John McDonald
1
Obrigado, acabei de dizer o que você já disse. Mas um pouco diferente.
MarkR
0

Você pode tentar alocar uma matriz de pixels compondo um bitmap de cada valor getRGB () de cada pixel individual. Em seguida, compare os valores com uma instrução if, pois as bordas do ladrilho são um valor de cor separado do que o que o ladrilho representa (água, areia, grama). Isso para uma grade isométrica básica. Ou você pode ter duas camadas do próprio mapa. Uma camada contendo uma espécie de tela verde desenhando o contorno de cada representante de um objeto em colisão e a outra camada será o próprio mapa.

Você não está compondo uma matriz de bitmap de cada pixel da camada do mapa, mas deseja calcular um conjunto de cores que representam os efeitos que ela tem quando um objeto colide / cruza a borda do valor da cor de manutenção. Você deseja que os valores diminuam ou aumentem a velocidade na qual o objeto está se movendo. Cada objeto que se move é apenas uma duplicata da memória armazenada em um local diferente.

Eu procuraria uma colisão perfeita de pixels e o entendimento de matrizes de bitmap. Cada retângulo é um limite para conter dados de replicação, como memória impressa, cada evento é acionado dependendo de onde um objeto é renderizado em um local ou vetor. Cada ponto da tela está em um plano 2D apenas que a profundidade da sombra fornece uma ilusão de que o objeto se representa como 3D. A transformação de formas em uma inclinação dá a sensação de que o objeto está em ângulo. Há um ponto central em que a câmera apresenta a visualização de tudo o que é transportado em torno desse ponto central, afastando-se dele diminuindo de tamanho ou aproximando-se dele aumentando de tamanho.

Олег Игоревич
fonte