Eu implementei uma rotina simples de detecção de colisão usando AABB's entre meu sprite de jogo principal e várias plataformas (consulte o código abaixo). Funciona muito bem, mas agora estou introduzindo a gravidade para fazer meu personagem cair e isso mostrou alguns problemas com a rotina do meu CD.
Eu acho que o cerne da questão é que minha rotina de CD move o sprite de volta ao longo do eixo em que ele penetrou a menor quantidade no outro sprite. Portanto, se ele estiver mais no eixo Y do que no X, ele será movido de volta ao longo do eixo X.
No entanto, agora meu sprite (herói) está caindo a uma taxa de 30 pixels por quadro (é uma tela de 1504 de altura - eu preciso que caia tão rápido quanto eu quero tentar simular a gravidade 'normal', qualquer velocidade mais lenta parece estranha ) Estou recebendo esses problemas. Vou tentar mostrar o que está acontecendo (e o que acho que está causando isso - embora não tenha certeza) com algumas fotos: (Código abaixo das fotos).
Gostaria de receber algumas sugestões sobre como contornar esse problema.
Para esclarecimento, na foto acima, quando digo que a posição está corrigida 'incorretamente', isso talvez seja um pouco enganador. O código em si está funcionando corretamente para como ele é escrito, ou dito de outra forma, o próprio algoritmo se comportando como eu esperaria, mas preciso alterar o comportamento para impedir que esse problema aconteça, espero que esclareça meus comentários na imagem .
My Code
public boolean heroWithPlatforms(){
//Set Hero center for this frame
heroCenterX = hero.xScreen+(hero.quadWidth/2);
heroCenterY = hero.yScreen+(hero.quadHeight/2);
//Iterate through all platforms to check for collisions
for(x=0;x<platformCoords.length;x+=2){
//Set platform Center for this iteration
platformCenterX = platformCoords[x]+(platforms.quadWidth/2);
platformCenterY = platformCoords[x+1]+(platforms.quadHeight/2);
// the Dif variables are the difference (absolute value)
// of the center of the two sprites being compared (one for X axis difference
//and on for the Y axis difference)
difX = Math.abs(heroCenterX-platformCenterX);
difY = Math.abs(heroCenterY-platformCenterY);
//If 1
//Check the difference between the 2 centers and compare it to the vector (the sum of
//the two sprite's widths/2. If it is smaller, then the sprites are pverlapping along
//the X axis and we can now proceed to check the Y axis
if (difX<vecXPlatform){
//If 2
//Same as above but for the Y axis, if this is also true, then we have a collision
if(difY<vecYPlatform){
//we now know sprites are colliding, so we now need to know exactly by how much
//penX will hold the value equal to the amount one sprite (hero, in this case)
//has overlapped with the other sprite (the platform)
penX = vecXPlatform-difX;
penY = vecYPlatform-difY;
//One sprite has penetrated into the other, mostly in the Y axis, so move sprite
//back on the X Axis
if (penX < penY){hero.xScreen-=penX*(heroCenterX-platformCenterX>=0 ? -1 : 1);}
//Sprite has penetrated into the other, mostly in the X asis, so move sprite
//back on the Y Axis
else if (penY < penX) {hero.yScreen-=penY*(heroCenterY-platformCenterY>=0 ? -1 : 1);}
return true;
}//Close 'If' 2
} //Close 'If' 1
}
//Otherwise, no collision
return false;
}
//One sprite has penetrated into the other, mostly in the Y axis, so move sprite //back on the X Axis