A lot of your problems seem to come from bundling together all of your checks and causing conflicts. Try separating your functions based on what direction your going and what collisions can happen in that direction to avoid more confusion. For example if your moving up you only need to check for player top collisions. You don't need to check whether or not you've collided with the bottom, left, or right walls.
Well now I'm trying it your way as I'm more comfortable with this method, can't be looking through tons of code right now to solve this simple task.
Unfortunately, I'm still getting stuck along the edges, even when I check against what directions I'm going.
Here's a picture showing what's happening now for the following cases I'm testing (I only test two cases for now since there's no point in going forward if my player is all ready getting stuck):
Currently right now I have the following cases:
- Player is going up but NOT left or right (only going up)
- Player is going up AND left, but not right (up and left)
Even with just two cases so far, the player is all ready getting stuck..
If my player is going up and left, and he's colliding against the right side of the block, its smooth! Perfect, right?
If my player is going up, I'm only checking collision against the bottom of the block, it works! Perfect, right?
Well if my player is going up and left and he's colliding against the bottom of the blocks, as he glides to the left
across the bottom of the blocks, he gets stuck on the edges between the two blocks. (x = brect.right + 1)
This is bad, and it's the exact same thing that was happening before.
Here are my collision functions:
//player right collides with box left
bool SFMLPlayer::check_pright_bleft(RECTANGLE* _prect, RECTANGLE* _brect, int move_speed){
RECTANGLE prect = *_prect;
RECTANGLE brect = *_brect;
int offset = move_speed;
if(prect.right > brect.left && prect.right <= brect.left + offset){
if ( (prect.top >= brect.top && prect.top < brect.bottom) ){
return true;
}
else if ( (prect.bottom >= brect.top && prect.bottom < brect.bottom) ){
return true;
}
}
return false;
}
//player left collides with box right
bool SFMLPlayer::check_pleft_bright(RECTANGLE* _prect, RECTANGLE* _brect, int move_speed){
RECTANGLE prect = *_prect;
RECTANGLE brect = *_brect;
int offset = move_speed;
if(prect.left < brect.right + offset && prect.left > brect.right - offset){
if ( (prect.top >= brect.top && prect.top < brect.bottom) ){
return true;
}
else if ( (prect.bottom >= brect.top && prect.bottom < brect.bottom) ){
return true;
}
}
return false;
}
//player bottom collides with box top
bool SFMLPlayer::check_pbottom_btop(RECTANGLE* _prect, RECTANGLE* _brect, int move_speed){
RECTANGLE prect = *_prect;
RECTANGLE brect = *_brect;
int offset = move_speed;
if(prect.bottom > brect.top && prect.bottom <= brect.top + offset){
if( (prect.right >= brect.left && prect.right < brect.right) ){
return true;
}
else if( (prect.left >= brect.left && prect.left < brect.right) ){
return true;
}
}
return false;
}
//player top collides with box bottom
bool SFMLPlayer::check_ptop_bbottom(RECTANGLE* _prect, RECTANGLE* _brect, int move_speed){
RECTANGLE prect = *_prect;
RECTANGLE brect = *_brect;
int offset = move_speed;
if(prect.top < brect.bottom && prect.top >= brect.bottom - offset){
if( (prect.right >= brect.left && prect.right < brect.right) ){
return true;
}
else if( (prect.left >= brect.left && prect.left < brect.right) ){
return true;
}
}
return false;
}
And here is where I'm using the test cases, inside the block iteration (looping through all blocks in the vector):
for(std::vector<Block>::iterator block = blocks->begin(); block != blocks->end(); ++block) {
RECTANGLE prect;
prect.left = this->x;
prect.top = this->y;
prect.right = this->x + this->size;
prect.bottom = this->y + this->size;
RECTANGLE brect;
brect.left = block->x;
brect.top = block->y;
brect.right = block->x + block->size;
brect.bottom = block->y + block->size;
//AABB collision approach
int offset = move_speed;
//We are ONLY going up, check the top of player against bottom of block
if(up && !right && !left){
if( check_ptop_bbottom(&prect, &brect, move_speed) ){
y = brect.bottom+1;
}
}
//We are going UP AND LEFT, check the left side of player against right side of block,
//AND also check the top of player against bottom of block (we could be on the right side or bottom side of the block)
else if(up && (left && !right)){
if( check_pleft_bright(&prect, &brect, move_speed) ){
x = brect.right + 1;
}
else if( check_ptop_bbottom(&prect, &brect, move_speed) && prect.top > brect.top ){
y = brect.bottom;
}
}
}
Does anyone have any insight as to why my player gets stuck while gliding to the left along the bottom of the blocks,
yet he does not get stuck while gliding up along the right side of the blocks?
Where in my collision code, or even my test case code, is it allowing the player to stop moving to the left when he's on the bottom of the blocks and pushing up?
I've spent way too long on this and its unfortunately blocking me from doing any other work.
I've tried everything from changing an "<=" to an "<", placing offsets in different places, I just can't figure out how to make it so I can smoothly
glide across all sides. There's something wrong in my collision code and its incredibly hard to detect.