Como posso detectar o jogador sendo esmagado em um jogo de plataformas 2D?

19

Estou verificando a colisão quanto a um personagem de jogo de plataforma, como mostra o item 1. Os pontos vermelhos são os pixels marcados e as linhas cinza indicam os eixos aos quais pertencem. Gosto dos resultados obtidos ao verificar a colisão dessa maneira (versus, digamos, caixa delimitadora). Tudo funciona exatamente como eu gostaria, exceto por um problema: detecção de esmagamento.

Nas imagens a seguir, a caixa azul clara representa o chão, a caixa laranja é um objeto e as setas indicam a direção do movimento.

A solução simples para detectar quando o jogador é esmagado é verificar se os pontos de colisão em lados opostos estão sendo acionados. Se estiverem, o jogador está sendo esmagado. No segundo, você pode ver um cenário de queda normal. O jogador está aterrado e os pontos de colisão superiores estão se cruzando com o objeto em queda. Isso desencadeia uma queda.

Os números 3, 4 e 5 apresentam cenários problemáticos. Em # 3, o jogador está se movendo em direção ao objeto, que está se movendo para cima. Um ponto de colisão do lado direito está atingindo o objeto, causando uma colisão e parando o jogador.

Agora, se o objeto continuar se movendo para cima e o jogador continuar se movendo para a direita (como mostra a # 4), o objeto limpa o ponto de colisão do lado direito do jogador e o jogador se move para a direita. Mas agora, tendo feito isso, o objeto está cruzando um ponto de colisão superior, causando uma queda vertical indesejada.

Um cenário semelhante é mostrado em # 5. Dois objetos estão suficientemente distantes para que os pontos de colisão inferiores desapareçam, permitindo que o jogador caia, mas não o suficiente para permitir que os pontos de colisão laterais desapareçam, causando uma queda horizontal indesejada.

Estive procurando meu cérebro em uma solução, mas nada que tenha surgido funcionou particularmente bem, por isso estou me perguntando se alguém por aí tem uma ideia ou insight sobre como resolver esses problemas.

insira a descrição da imagem aqui

Para esclarecer alguma confusão, os pontos de colisão vermelhos estariam dentro do sprite e as linhas cinza foram usadas apenas para indicar o eixo relevante para cada ponto de colisão. Por exemplo, se o sprite do personagem fosse um quadrado verde simples, os pontos de colisão teriam algo parecido com isto:

insira a descrição da imagem aqui

IanLarson
fonte

Respostas:

34

Acho que você terá que levar em consideração o movimento da caixa . Ou seja, apenas esmague se a caixa estiver se movendo em direção ao jogador.

Isso é semelhante a outros problemas em plataformas, onde o movimento é importante. Por exemplo, para plataformas nas quais você pode saltar de baixo para cima, não verifique a colisão se o jogador estiver se movendo para cima.

Portanto, um bloco pode esmagar o jogador de cima apenas se o bloco estiver se movendo para baixo; de baixo apenas se o bloco estiver se movendo para cima; da esquerda somente se o bloco estiver se movendo para a direita e assim por diante.

congusbongus
fonte
13
+1 Leve em consideração que o bloco está agindo aqui, não o jogador. Então, se você verificar se a caixa está esmagando o jogador em vez de verificar se o jogador está sendo esmagado o problema deve ser mais fácil de resolver
Niels
E quando os blocos não estão se movendo? Percebo agora que coloquei flechas nos blocos do número 5, mas eram dois blocos fixos.
precisa saber é o seguinte
Se você decidir que blocos estacionários não devem ser esmagados, verifique se o jogador não está preso e pode sair do caminho.
congusbongus 29/09
Argh, eu odeio ser esmagado por dois objetos que realmente estão se afastando um do outro, apenas porque eu fiz isso perfeito em pixels e quadros e o desenvolvedor era preguiçoso.
Rinoceronte #
9

Faça com que os pontos de "teste de esmagamento" estejam dentro da caixa cinza mostrada na sua imagem # 1 - ou seja, mate o jogador apenas se detectar um acerto em um dos pixels lá.

Peter é
fonte
1
Você quer dizer pontos de verificação de esmagamento adicionais "dentro" dos limites dos pontos de colisão? O problema que vejo com isso é que a resolução de colisão ocorrerá em cada eixo quando um de seus pontos de colisão for "acionado" antes que o objeto tenha a chance de alcançar os pontos de verificação de esmagamento internos.
precisa saber é o seguinte
6

Como alguém que cresceu com plataformas dos anos 80, meu primeiro comentário é que os pontos de contato devem estar exatamente no sprite, e não em qualquer lugar fora dele. Houve poucas experiências mais frustrantes do que morrer quando uma arma / triturador / inimigo estava claramente a vários pixels de seu personagem - e esse tipo de experiência é o que impede as pessoas de jogar.

Com isso em mente, a idéia de ter pontos separados para colisão horizontal e vertical simplesmente não voa. Portanto, seus casos 3 e 5 não existem.

Quanto à detecção de colisão, como foi dito anteriormente, é necessário considerar a direção do movimento e você tem dois eixos de movimento a considerar. Se um britador estiver abaixado, o jogador não poderá andar para frente - ele deve agir como uma parede. Portanto, com pontos de detecção horizontais e verticais no mesmo local, você não pode obter o caso 4, mesmo antes de adicionar a direção do movimento à mistura.

O triturador ascendente adiciona complexidade extra. Se é tão rápido que o jogador não tem chance de escapar, tudo bem. Mas, se for mais lento, o jogador espera poder correr sobre a plataforma ascendente e pular do outro lado. O sprite do jogador sobe no triturador e a detecção de esmagamento acontece no teto .

Graham
fonte
3
Ponto secundário - você não sabe como é o sprite dele. Pelo que sabemos, pode ser exatamente como mostrado nas imagens acima; portanto, os casos 3 e 5 podem ser totalmente válidos.
Alex
1
Alex está certo. Eu fiz uma edição para esclarecer. Concordo que não há nada pior do que caixas de colisão inconstantes. Acho que entendi o seu ponto de não usar pontos separados para os diferentes eixos. Se sim, isso tornaria o exemplo acima de oito pontos para quatro, um em cada canto, correto? Na verdade, eu fiz alguns testes com isso em mente (com resultados menos do que desejáveis), mas estou fortemente hesitante em fazer isso, já que ter os cantos "separados" alcança o comportamento que estou procurando quase perfeitamente. Esses são realmente os únicos cenários de problemas em que me deparei.
precisa saber é o seguinte
0

Você pode tornar o objeto "mais duro" que o chão, o que significa que, assumindo uma colisão, o jogador é empurrado "para dentro" do chão, em vez de ser empurrado "para dentro" do objeto em movimento.

Isso pressupõe que o jogador não consiga empurrar-se "contra" objetos ou chão.

Zamfi
fonte
0

Se você puder detectar a sobreposição de objetos sem precisar esperar a exibição, uma abordagem simples é processar o movimento para o player e outros objetos de forma independente, um pixel de cada vez, com verificações de colisão separadas posteriormente. Se o jogador estiver se movendo livremente e colidir com seu objeto como resultado de tal movimento, afaste-o. Se ocorrer uma colisão com um objeto como resultado do movimento do objeto, verifique se o jogador pode se mover na mesma direção que esse objeto. Nesse caso, mova o player. Caso contrário, lide com a situação de "esmagamento" adequadamente (danificando ou matando o jogador e / ou movendo o objeto em colisão para trás, dependendo do contato).

BTW, se apenas um número limitado de combinações de formas puder colidir, pode ser útil pré-calcular bitmaps de "detecção de colisão", de modo que, se um pixel for definido no primeiro sprite no deslocamento (x1, y1) e no segundo no deslocamento (x2, y2) do segundo, o pixel no deslocamento (x1-x2, y1-y2) será definido no mapa de colisão. Esse mapa de colisão pré-calculado permitirá detectar colisões entre os dois sprites, verificando o estado de um único pixel no mapa de colisão.

supercat
fonte
0

São necessários dois objetos para esmagar um jogador. Sua detecção de queda deve verificar se o jogador está entre dois objetos, o espaço entre eles é igual ao tamanho do jogador e a distância diminuindo.

Acumulação
fonte
0

Acho que estou trabalhando até agora. Ele não requer informações "externas" sobre o movimento dos trituradores e resolve o problema dos falsos positivos. Quando um falso positivo é detectado, ele é tratado como colisão (e é isso que realmente é):

A idéia é: por que verificar se o britador está se movendo quando realmente nos importamos se o personagem está se movendo? Ambos podem responder se a queda é falsa positiva causada pelo movimento do próprio personagem ou queda verdadeira pelo movimento do objeto triturador.

Se o personagem estiver se movendo e esmagado (colisões nos lados opostos para o quadro recebido), verifique novamente se há esmagamento nas últimas coordenadas do quadro / iteração:

  1. Se não for confirmado novamente, é devido ao próprio movimento do personagem e o personagem deve ser retornado para as últimas coordenadas de quadro / iteração como uma colisão

  2. Se a queda for confirmada pela segunda vez, prossiga com a queda.

Nikaas
fonte