I implemented a simple collision detection routine using AABB's between my main game sprite and various platforms (Please see code below). It works great, but I'm now introducing gravity to make my character fall and it's shown up some problems with my CD routine.
I think the crux of the matter is that my CD routine moves the sprite back along the axis in which it has penetrated the least amount into the other sprite. So, if it's more in the Y axis than the X, then it will move it back along the X Axis.
However, now my (hero) sprite is now falling at a rate of 30 pixels per frame (It's a 1504 high screen - I need it to fall this fast as I want to try to simulate 'normal' gravity, any slower just look weird) I'm getting these issues. I will try to show what is happening (and what I think is causing it - although I'm not sure) with a few pictures: (Code below pictures).
I would appreciate some suggestions on how to get around this issue.
For clarification, in the above right picture, when I say the position is corrected 'incorrectly' that's maybe a bit misleading. The code itself is working correctly for how it is written, or put another way, the algorithm itself if behaving how I would expect it to, but I need to change it's behaviour to stop this problem happening, hope that clarifies my comments in the picture.
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
\$\endgroup\$