I have one RectangleShape for wall and I draw this one object for every "1" on my 2D map:
int map[5][8] =
{
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 1, 0, 1, 1, 0, 1 },
{ 1, 2, 1, 0, 0, 0, 3, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 }
};
sf::RectangleShape player;
player.setSize(sf::Vector2f(32,32));
sf::RectangleShape wall;
wall.setSize(sf::Vector2f(32,32));
wall.setFillColor(sf::Color(40, 199, 40));
for (int mapX= 0; mapX< 8; mapX++)
{
for (int mapY= 0; mapY< 5; mapY++)
{
if (map[mapY][mapX] == 1)
{
wall.setPosition(mapX * 32, mapY * 32);
window.draw(wall);
}
}
}
And I checking for collision with code listed down, but this works for only last drawn wall. How to fix this? Theres only one object wall and I want to check collision for all drawned walls for my 2D array map.
if (event.type == sf::Event::TextEntered)
{
fPlayerY_t = fPlayerY;
fPlayerX_t = fPlayerX;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) fPlayerY_t = fPlayerY - 32;
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) fPlayerY_t = fPlayerY + 32;
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) fPlayerX_t = fPlayerX + 32;
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) fPlayerX_t = fPlayerX - 32;
// temp pos
player.setPosition(fPlayerX_t, fPlayerY_t);
// collision with wall
if (player.getPosition().x == wall.getPosition().x &&
player.getPosition().y == wall.getPosition().y)
{
// back to prev position
player.setPosition(fPlayerX, fPlayerY);
}
else
{
// No collision
fPlayerX = fPlayerX_t;
fPlayerY = fPlayerY_t;
}
}
Convert the coordinates of the player in array coordinates then check if map[x][y] == 1
.
So do not have to loop through your entire map every game loop.
To convert into array coordinates, use int
conversion :
int playerTileX = (int)(playerWorldX / 32);
int playerTileY = (int)(playerWorldY / 32);
if(map[playerTileX ][playerTileY ] == 1)
{
// collision.
}
else
{
// no collision.
}
What I dislike with this solution : it only checks for tiles collision, you have to be sure every wall is the same size (here 32*32).