I'm creating a game in C++ using SFML library, and during implementation tile map collision(i'm loading map from txt file - 1's stand for platforms, 0's for free space). https://imgur.com/a/tQZc6
I came across a problem with handling all four type of collisions at the same time(from bottom, top, left and right).What I mean: when there is no collision, the player can normally move, but if we hit the wall, collision appears only for FIRST written if() statement(in our example only right collision occurs, rest are being omitted). Here's my code (i'll paste only necessary things)
class Player
{
public:
Player();
Player(sf::Texture* texture, sf::Vector2u imageCount, sf::Vector2f position, float switchTime, float speed, float jumpSpeed);
~Player();
void UpdatePlayer(float deltaTime);
float top, right, left, bottom;
private:
sf::Vector2f _position;
float groundHeight = 40; //i've added gravity and hardcoded the ground height to create jumping
float _jumpSpeed; // later on, it will be replaced with bottom collision
const float gravity = 981.0f;
sf::RectangleShape body;
float _speed;
};
//Player.cpp
void Player::UpdatePlayer(float deltaTime)
{
sf::Vector2f movement(0.0f, 0.0f);
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
movement.x -= _speed * deltaTime; //we are using delta time in order to move the object in according to time
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
movement.x += _speed * deltaTime;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
movement.y = -sqrt(5.0f * gravity * _jumpSpeed) * deltaTime;
}
if (body.getPosition().y + body.getSize().y < groundHeight || movement.y < 0)
{
movement.y += gravity * deltaTime;
}
else
{
body.setPosition(body.getPosition().x, groundHeight - body.getSize().y);
movement.y = 0;
}
bottom = body.getPosition().y + body.getSize().y;
left = body.getPosition().x;
right = body.getPosition().x + body.getSize().x;
top = body.getPosition().y;
body.move(movement);
}
//Source.cpp
void LoadCollisionMap(const char*filename)
{
std::ifstream openfile(filename);
std::vector<int> tempMap;
CollMap.clear();
if (openfile.is_open())
{
while (!openfile.eof())
{
std::string str, value;
std::getline(openfile, str);
std::stringstream stream(str);
while (std::getline(stream, value, ' '))
{
if (value.length() > 0)
{
int a = atoi(value.c_str());
tempMap.push_back(a);
}
}
CollMap.push_back(tempMap);
tempMap.clear();
}
}
}
int main()
{
LoadCollisionMap("Map2.txt"); //Collision map
Player player(&playerTexture, sf::Vector2u(3, 9),sf::Vector2f(100.0f, 150.0f) ,0.3f, 400.0f, 555.0f);
for (int i = 0; i < CollMap.size(); i++)
{
for (int j = 0; j < CollMap[i].size(); j++)
{
if (CollMap[i][j] == 1)
{
int CollBottom, CollRight, CollLeft, CollTop;
CollBottom = i * 32 + 32;
CollTop = i * 32;
CollLeft = j * 32;
CollRight = j * 32 + 32;
if (player.right < CollLeft || player.left > CollRight || player.top > CollBottom || player.bottom < CollTop)
{
//no collision
}
else
{
if (player.right > CollLeft)
{
std::cout << "collision" << std::endl;
player.body.setPosition(player.body.getPosition().x - 1, player.body.getPosition().y);
break;
}
if (player.left < CollRight)
{
std::cout << "collision 2" << std::endl;
player.body.setPosition(player.body.getPosition().x + 1, player.body.getPosition().y);
break;
}
if (player.top < CollBottom)
{
std::cout << "collision 3" << std::endl;
player.body.setPosition(player.body.getPosition().x, player.body.getPosition().y + 1);
break;
}
if (player.bottom > CollTop)
{
std::cout << "collision 4" << std::endl;
player.body.setPosition(player.body.getPosition().x, player.body.getPosition().y - 1);
break;
}
}
}
}
}