Ok, então este é um problema que venho tentando descobrir há algum tempo. O Mine é um jogo de plataformas 2D com um mundo composto de (geralmente) blocos imóveis e sprites móveis, os quais usam AABBs para representar seus hitboxes. Este jogo NÃO é baseado em grade devido a algumas complicações com a movimentação de camadas de peças.
Eu posso detectar colisões e descobrir facilmente a profundidade da colisão. Eu uso o "método de eixo mais raso" para determinar qual caminho resolver uma colisão entre o sprite e o ladrilho. Se o sprite for mais profundo horizontalmente do que verticalmente, a direção a ser resolvida é para cima ou para baixo. Se o sprite for mais profundo verticalmente do que horizontalmente, a direção a ser resolvida é esquerda ou direita.
Isso é bastante simples e funciona muito bem. Ou seja, até que você tenha um sprite colidindo com mais de um bloco. Como, por sua natureza, cada colisão deve ser verificada separadamente, diferentes colisões podem ter uma direção diferente para resolver. Por exemplo, se um sprite estiver tentando atravessar uma fileira de ladrilhos, para um quadro, eles cruzarão o próximo ladrilho, como que a profundidade horizontal é menor que a profundidade vertical. Como a colisão diz "resolva à esquerda", ela será empurrada para trás e ficará presa na esquina.
Venho refletindo sobre esse problema há muito tempo, e há várias soluções para mim, mas todas têm falhas. Eu poderia marcar certos lados como inacessíveis, mas sem um mecanismo baseado em grade, a determinação de "inacessibilidade" é notavelmente complexa, especialmente com a possibilidade de mover camadas de ladrilhos sempre.
Outro método possível seria prever colisões antes que elas aconteçam e "retroceder" o movimento até o ponto da colisão, suponho, mas não tenho certeza de como a matemática funciona.
Sinto que estou perdendo algo incrivelmente óbvio, principalmente porque os jogos dos anos 80 já resolveram esse problema.