I am currently working on a small 2D Games Engine with SDL2 for fun. The engine works in a way, that you can define a tileset, which accesses the engine and allows you to place tile by tile on the predefined window and specify what type of tile you want to place. If it should have collision or if it should rotate. My bug occurs by the collision with the player.
I seperate the block i want the player to collide with into 8 blocks(4 side-blocks and 4 Corner-blocks).If my player now collides with an tile, the program checks,which part of the tile the player has collided with and then pushes the player in a certain direction dependend on the block of the tile it collided with.
This is the code for the collision:
int Editor::Collision(EDITOR_BODY body)
{
int rect = 0;
for (int i = 0; i < tile_type.size(); i++)
{
if (tile_type.at(i) == ITEM_HITBOX)
{
#define COL(a,b) (a.x+a.w>b.x&&a.x<b.x+b.w&&a.y+a.h>b.y&&a.y<b.y+b.h)
SDL_Rect corner_ur, corner_ul, corner_dr, corner_dl, side_l, side_r, block_u, block_d;
corner_ul = {
tiles.at(i)->GetX(),
tiles.at(i)->GetY(),
tiles.at(i)->GetWidth() / 8,
tiles.at(i)->GetHeight() / 8
};
corner_ur = {
tiles.at(i)->GetX()+tiles.at(i)->GetWidth()*7/8,
tiles.at(i)->GetY(),
tiles.at(i)->GetWidth() / 8,
tiles.at(i)->GetHeight() / 8
};
corner_dr = {
tiles.at(i)->GetX()+tiles.at(i)->GetWidth()*7/8,
tiles.at(i)->GetY()+tiles.at(i)->GetHeight()*7/8,
tiles.at(i)->GetWidth() / 8,
tiles.at(i)->GetHeight() / 8
};
corner_dl = {
tiles.at(i)->GetX(),
tiles.at(i)->GetY() + tiles.at(i)->GetHeight() * 7 / 8,
tiles.at(i)->GetWidth() / 8,
tiles.at(i)->GetHeight() / 8
};
side_r = {
tiles.at(i)->GetX() + tiles.at(i)->GetWidth() * 7 / 8,
tiles.at(i)->GetY() + tiles.at(i)->GetHeight()/ 8,
tiles.at(i)->GetWidth() / 8,
tiles.at(i)->GetHeight()*6 / 8
};
side_l = {
tiles.at(i)->GetX() ,
tiles.at(i)->GetY() + tiles.at(i)->GetHeight() / 8,
tiles.at(i)->GetWidth() / 8,
tiles.at(i)->GetHeight() * 6 / 8
};
block_u = {
tiles.at(i)->GetX()+ tiles.at(i)->GetWidth()/ 8 ,
tiles.at(i)->GetY(),
tiles.at(i)->GetWidth()*6 / 8,
tiles.at(i)->GetHeight() /2
};
block_d = {
tiles.at(i)->GetX() + tiles.at(i)->GetWidth() / 8 ,
tiles.at(i)->GetY()+ tiles.at(i)->GetHeight() / 2,
tiles.at(i)->GetWidth() * 6 / 8,
tiles.at(i)->GetHeight() / 2
};
if (COL(corner_ul, body))rect=1;
if (COL(corner_dl, body))rect = 2;
if (COL(corner_ur, body))rect = 3;
if (COL(corner_dr, body))rect = 4;
if (COL(side_r, body))rect = 5;
if (COL(side_l, body))rect = 6;
if (COL(block_u, body))rect = 7;
if (COL(block_d, body))rect = 8;
//Release the next comment for testing purposes..
SDL_SetRenderDrawColor(setup->GetRenderer(), 255,0, 0, 255);
SDL_RenderFillRect(setup->GetRenderer(), &corner_ur);
SDL_RenderFillRect(setup->GetRenderer(), &corner_ul);
SDL_RenderFillRect(setup->GetRenderer(), &corner_dr);
SDL_RenderFillRect(setup->GetRenderer(), &corner_dl);
SDL_SetRenderDrawColor(setup->GetRenderer(), 0,255, 0, 255);
SDL_RenderFillRect(setup->GetRenderer(), &side_r);
SDL_RenderFillRect(setup->GetRenderer(), &side_l);
SDL_SetRenderDrawColor(setup->GetRenderer(), 0, 0,255, 255);
SDL_RenderFillRect(setup->GetRenderer(), &block_u);
SDL_RenderFillRect(setup->GetRenderer(), &block_d);
SDL_SetRenderDrawColor(setup->GetRenderer(), 255, 255, 255, 255);
if (COL(corner_ul, body))SDL_RenderFillRect(setup->GetRenderer(),&corner_ul);
if (COL(corner_dl, body))SDL_RenderFillRect(setup->GetRenderer(), &corner_dl);
if (COL(corner_ur, body))SDL_RenderFillRect(setup->GetRenderer(), &corner_ur);
if (COL(corner_dr, body))SDL_RenderFillRect(setup->GetRenderer(), &corner_dr);
if (COL(side_r, body))SDL_RenderFillRect(setup->GetRenderer(), &side_r);
if (COL(side_l, body))SDL_RenderFillRect(setup->GetRenderer(), &side_l);
if (COL(block_u, body))SDL_RenderFillRect(setup->GetRenderer(), &block_u);
if (COL(block_d, body))SDL_RenderFillRect(setup->GetRenderer(), &block_d);
}
}
return rect;
}
My problem ist, that when the player stands on the right coordinats, that he is paralell to a tile, but hits a corner block first, he is able to clip through an block.
Here is a picture, that shows the bug:
Maybe you can tell me how to avoid this Problem, or if there is a better way to handle such collisions