1
\$\begingroup\$

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):
Shows the way my current collision checking should work

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)

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You might want to check out the other questions that are related to this one on this site. \$\endgroup\$ Apr 1 at 21:54
  • \$\begingroup\$ I did but im to dumb to implement it myself qwq \$\endgroup\$
    – Mia
    Apr 2 at 8:39

0

You must log in to answer this question.

Browse other questions tagged .