Hi i want to implement a collision system (something comparable to super mario)
I would like it to have objects which can have any size (the hitbox of it)
And it should be reasonably efficient (so nothing like checking every tile in the map)
Slopes and other forms of tiles are optional
I would like a non theoretical answer bc im to dumb to implement it... (i really tried) but thats also optional
Also we can assume that the tiles x and y sizes are the same (f.e. 32x32)
Explanation for the code i have written so far:
IS_SOLID
just checks if the block at (x,y)/TILESIZE is a solid block (so it should be affecting the collisions)
TFP_X
/TFP_Y
are just input/TILESIZE (so it gets the tile pos form coordinates)
#include "Components.hpp"
#include "../Game.hpp"
void CollisionComponent::main() {
physics->applayGravity();
newPos = physics->transform->position + physics->velocity * SPEED;
if (newPos.y < 0) {
physics->transform->position = newPos;
return;
}
// Y cords
// Moving up
if (physics->velocity.y <= 0) {
// Check the most right point
if (IS_SOLID((newPos.x + texture->getSize()->x), newPos.y)) {
physics->velocity.y = 0;
newPos.y = (TFP_Y(newPos.y)) * TILESIZE_Y - 1;
} else {
for (Uint8 xP = 0; xP < static_cast<int>(texture->getSize()->x / TILESIZE_X); xP++) {
// check for points
if (IS_SOLID(newPos.x + static_cast<float>(xP * TILESIZE_X), newPos.y)) {
physics->velocity.y = 0;
newPos.y = (TFP_X(newPos.y)) * TILESIZE_Y - 1;
break;
}
}
}
} else { // Moving down
// Check the most right point
if (IS_SOLID((newPos.x + texture->getSize()->x), (newPos.y + texture->getSize()->y))) {
physics->velocity.y = 0;
newPos.y = (TFP_Y(newPos.y) + 1) * TILESIZE_Y - texture->getSize()->y % TILESIZE_Y;
} else {
for (Uint8 xP = 0; xP < static_cast<int>(texture->getSize()->x / TILESIZE_X); xP++) {
// check for points
if (IS_SOLID(newPos.x + static_cast<float>(xP * TILESIZE_X), (newPos.y + texture->getSize()->y))) {
physics->velocity.y = 0;
newPos.y = (TFP_Y(newPos.y) + 1) * TILESIZE_Y - texture->getSize()->y % TILESIZE_Y;
break;
}
}
}
}
// X cords
// Moving left
if (physics->velocity.x <= 0) {
// Check the lowest point
if (IS_SOLID(newPos.x, (newPos.y + texture->getSize()->y))) {
physics->velocity.x = 0;
newPos.x = (TFP_X(newPos.x) + 1) * TILESIZE_X;
} else {
for (Uint8 yP = 0; yP < static_cast<int>(texture->getSize()->x / TILESIZE_X); yP++) {
// check for points
if (IS_SOLID(newPos.x, (newPos.y + static_cast<float>(yP * TILESIZE_Y)))) {
physics->velocity.x = 0;
newPos.x = (TFP_X(newPos.x) + 1) * TILESIZE_X;
break;
}
}
}
} else { // Moving right
// Check the lowest point
if (IS_SOLID((newPos.x + texture->getSize()->x), (newPos.y + texture->getSize()->y))) {
physics->velocity.x = 0;
newPos.x = (TFP_X(newPos.x) + 1) * TILESIZE_X - texture->getSize()->x % TILESIZE_X;
} else {
for (Uint8 yP = 0; yP < static_cast<int>(texture->getSize()->x / TILESIZE_X); yP++) {
// check for points
if (IS_SOLID((newPos.x + texture->getSize()->x), (newPos.y + static_cast<float>(yP * TILESIZE_Y)))) {
physics->velocity.x = 0;
newPos.x = (TFP_X(newPos.x) + 1) * TILESIZE_X - texture->getSize()->x % TILESIZE_X;
break;
}
}
}
}
physics->transform->position = newPos;
}
The way my current system should check for collisions (well the points where it checks for collisions):
My current system should check every TILESIZE pixels for an collision (and the last point)
My problem is that it just doesnt work in any way i want to lol
1: It doesnt have a way to decide which way to act (bc it doesnt 'know' if it should move the player in the x or y coordinates) and every way i tried to implement it failed ><
So it just moves the player to the left when standing on top (a little bit inside) of a block instead of moving it on top of the block
2: (optional) it doesnt handle anything else than normal blocks (i would love one-way platforms and something like slopes)
If you have any more questions please feel free to ask or just message me on discord (Miaaa#6340)