# How do you get player to interact with level?

I suffer from this problem where I have say a class called Player and a class called Level. Now the only way I can figure out how to say make the player interact with the level is if I do something like

player.input();

level.update(player);


I would have to do something like that, but then it gets even more complicated if I have monsters and I need to add them to the level e.t.c., so how do I get the monsters to interact with the player.

So I'm struggling with this basic concept. If I use C it gets rid of this problem as I use extern and I can get the data I want so all I think about is the flow. So in C I can do something like this

switch (terrain[u.y + dy][u.x + dx])
{
case WALL:
print_msg("You cannot go there.\n");
return 0;
case FLOOR:
case DOOR:
case STAIRS:
reloc_player(u.y + dy, u.x + dx);
return 1;
}


So in here we have Player u and your moving that player around only if it doesn't hit a wall. But, I can do this because I use extern on terrain[][].

I'm really struggling. I don't really want to use C as C++ is easier with SFML and I like classes. I suppose the answer is how do I manage interaction between level, mobs and players?

If I was going to do it now I would do this

Game::Game()
{
level.init();
player.init();
}

void Game::input()
{
player.input(level.getLevel()); // so yucky
}

void Game::update()
{
player.update();
level.update(player); /// yuck
}

void Game::render()
{
player.render();
level.render();
}


I could do something like this, but it gets really complicated and everything becomes a mess of passing stuff around. In particularly I need to pass the player method to the level.update() so the level knows the player has moved. Everything gets messy and I feel I can't add into the game. Plus I would need to make the level static or something.

• Can the player be part of the level? Ie the level owns player? When you call level.update(), it calls player.update(this)... alternatively, you could do it the other way round, where the player has-a-reference-to the level. – ThorinII Nov 28 '13 at 0:12
• I think this is a terrible title for a good question. "How to get player to interact with level" is incredibly vague; your actual question is more like "How to structure the Player and Level objects so that they can interact?" – jhocking Nov 28 '13 at 15:36

In object-oriented programming, you expose private data with getter-methods.

When your player-class wants to know the terrain-type of a tile, it would call level.getTerrain(int x, int y). That public function of class Level would access the private terrain array and returns the value of the terrain tile.

When you don't want the player-class to depend on the level-class (which is not a bad idea at all), you would not make the player-class responsible for performing its own actions. Instead of that you would have a PlayerController class which knows both the player and the level. It would first ask the player-class what it wants to do. Then it would check the level to see if it can do that. And then it would decide what the player-class really does and make it perform that action. Some incomplete pseudocode:

 public void PlayerController::update() {
// ask the player what it wants to do
Action action = player.getCurrentAction();
if (action == Action.MOVE_RIGHT) {
// decide what the outcome is
switch (level.getTerrain((player.getX() + 1, player.getY())) {
case Terrain.FLOOR:
case Terrain.DOOR_OPEN:
player.moveTo(player.getX() + 1, player.getY());
break;
case Terrain.WALL:
case Terrain.TREE:
player.speak("ouch!");
player.changeHitPoints(-1);
break;
case Terrain.DOOR_CLOSED:
level.setTerrain((player.getX() + 1, player.getY(), Terrain.DOOR_OPEN);
break;
}
}
}