The simplest approach is to separate the world coordinates from the screen coordinates. Let's make our game follow a grid, so the player is always in a specific tile and has integer coordinates. For example
struct Player {
int tileX;
int tileY;
};
Player p;
if (press left) p.tileX -= 1;
// etc..
When we draw the player, we then map his tileX, tileY world coordinates to the screen. For example:
... draw ...
sf::RectangleShape shape(sf::Vector2f(playerWidth,playerHeight));
shape.setFillColor(sf::Color::Red);
shape.setPosition(player.tileX * 32, player.tileY * 32);
(The 32 is how many screen pixels wide a tile is.)
We can now detect what tile the player is on, just by looking into that const int level array. For example:
int tileUnderPlayer = level[player.tileX + player.tileY*16];
if (tileUnderPlayer==1){
// player is in the water!!
}
Lastly .. to stop the player from entering a tile, we need to detect which tile he is about to step on before he actually moves there. E.g.,
if (press left){
if (player.tileX==0){ /* do nothing, we are at the edge */ }
else {
int newX = player.tileX - 1;
int newY = player.tileY;
int tile = level[newX + newY*16];
if (tile==1){
// can't move here, there's water here!
}
else {
// Can move here..
player.tileX = newX;
player.tileY = newY;
}
}
}
Hope this helps!
(Be extra careful when changing tileX, tileY to make sure it doesn't go out of bounds, otherwise your array lookup might throw a memory access violation.)