My way to make a game map in the console.

simple enough...

This post most likely contains either an error or something somebody disagrees with. This is just my way to do this,If you have other (or better) ways to do this, please share as well.

I have decided to put up my way (one of) of how to make a game map/world for a text rpg in the console.

After reading posts on various forums I have seen one common question is "How do I make the game map". One way to do this in the console is to use a double nested for loop to draw a x*x grid (see the dungeon crawler thread) and then place objects represented by text onto said grid and then have it do when you make a move it redraws the grid/map with the updated values. Blarg.

This is a much simpler and to the point way.

My example will use a coordinate systems to represent a game world and place events/objects/battles/etc at various X/Y coordinate values.

First with classes:

Lets say you have your Character class. In your main() you have made a new Character called Hero. Your Character class may look like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Character{

public:

    int getXCoord();
    void setXCoord(int xCoord);

    int getYCoord();
    void setYCoord(int yCoord);

private:
    int itsXCoord;
    int itsYCoord;

};


then in your main() you would put

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include "Character.h"
using namespace std;

int main()
{
Character Hero;
Hero.setXCoord(0);
Hero.setYCoord(0);

return 0;
}


Ok, so now we have a Hero, and its X/Y values are 0,0. The point of this is so you can now create a move function or loop that will then change either the x or y Coord value +/-. With this system it would be something like:

You find yourself in a forest. You can move North/South/West/East. The player then picks one of the choices given and the program changes the values of X/Y. Say the player decides to move north. Your program will add 1 to the X value. Now you are at 1.0. How is this useful? It is useful because it allows you to make a virtually infinite sized world and set conditional events at certain X/Y locations. For example: If a player moves to 3/-2 on your world, then perhaps a battle happens:
1
2
3
if (Hero.getXCoord() == 3 && Hero.getYCoord() == -2){
orcAmbush(); // don;t bother trying to compile this, orcAmbush has not been declared, used as an example
}


Now lets say we want to move around. You have told your player they are in *insert background story* and you cout the current location (0,0). You then want the player to be able to move around your world. Two ways to do this are by using either a playerMove(); function or a loop/nested if series. I will used the latter since using a playerMover function outside of the main scope requires pointers and ...no.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include "Character.h"
using namespace std;

int main()
{
int move;
Character Hero;
Hero.setXCoord(0);
Hero.setYCoord(0);
cout << "You are at :" << Hero.getXCoord() << ", " << Hero.getYCoord() << endl;
cout << "You find yourself in a clearing. Make a move\n";
cout << "1)North 2)South 3)East 4)West: ";
cin >> move;
if (move == 1){
    Hero.setXCoord(Hero.getXCoord()+1);
}
if (move == 2){
    Hero.setXCoord(Hero.getXCoord()-1);
}
if (move == 3){
    Hero.setYCoord(Hero.getYCoord()-1);
}
if (move == 4){
    Hero.setYCoord(Hero.getYCoord()+1);
}

cout << "Currently you are at: " << Hero.getXCoord() << ", " << Hero.getYCoord();

return 0;
}


Of course this only allows one move, but you can use this type of setup in a loop or a function as well.

Now, to do this all without classes, which is much simpler but much more restrictive on what your player can do (since you lose the class):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;

int main()
{
int move;
int xCoord = 0;
int yCoord = 0;

cout << "You are at :" xCoord << yCoord <, endl;
cout << "You find yourself in a clearing. Make a move\n";
cout << "1)North 2)South 3)East 4)West: ";
cin >> move;
if (move == 1){
    xCoord++;
    }
    
/*repeat for rest of choices*/

return 0;
}


This method is much shorter but is restrictive since you can't really do much if you want your x/y to be assigned to a player class. I wanted to show both methods though.

To be honest in my unprofessional opinion the best way to do this type of map/grid/world is to use the class and have a movePlayer() function. I would try to write it but its 4:40am and I just can't focus...

ps: the .cpp is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "Character.h"

    int Character::getXCoord(){
    return itsXCoord;
    }

    int Character::setXCoord(int xCoord){
    itsXCoord = xCoord;
    }

    int Character::getYCoord(){
        return itsYCoord;
    }

    int Character::setYCoord(int yCoord){
        itsYCoord = yCoord;
    }
hmm, I guess that's ok with really simple maps. I think it would be more complicated to implement in a map with a lot of stuff though. For example, if your map has a lot of walls and stuff. then you'd have to check every coordinate for every wall just to determine if you can pass that coordinate or not. Unlike if you use a char grid to represent the map, then all you'll have to do is check if the coordinate you're going to represents a wall, so you'll only have to check it once.

And another potential issue I see with doing it that way is the events or objects will keep repeating? So if there is a key in this coordinate, and I go to it and pick up the key, the next time I visit that coordinate again then the key would be there again. So you'll need to create another array inside your class or something that would just keep track if you have already visited each coordinate with specific events and items. That would seem to defeat the purpose though, since you didn't want to use a grid in the first place.

Anyways that's just my opinion on that, though I'm not really sure. Maybe it depends on how you implement it. I'd sure like to see more code on the way you implement that, before I jump into any conclusions. ^_^
Well, this was meant more for an outdoor map. It is easier this way to make very large maps I feel, but for smaller room with walls a char grid may work better.

As for the second point, I guess what I would do is if I had a key at lets say 0,4 then I would have a if statement and a bool following it. If Hero's location is 0,4 hasGoldKey = true removeGoldKey = true (or alternatively removeGoldKey();). I suppose with many objects it could get a little jumbled though...

As noted before, this is just one of I am sure many many ways to do this.

P.s. for walls and the like you could use a “If hero is at 0,5 tell the hero “you cannot go any further” and set the hero’s position to where it was before.
Well, this does look very nice, but a suggestion.

Make the "itsXCoord" and "itsYCoord" variables public instead of private, then that way you can get rid of having to use 4 functions to access and change variables. The two coordiantes aren't really sensative data (like what a player named his character, or his base stats), so there isn't the need for those extract functions.

Like instead of having to do this:
Hero.setXCoord(Hero.getXCoord()+1);

You could just do this:
Hero.itsXCoord += 1;

It's just a matter of ease of access vs. sensativity of data.
Last edited on
closed account (S6k9GNh0)
Seriously, I fail to see why you guys don't understand why to keep your variables abstract. Say you wanted a library that used this and you need to call a hook function whenever SetXCoord is called.

1
2
3
4
5
6
void SetXCoord(int _coord)
{
    xCoord = _coord;
    if (xCoordSetCallback != NULL)
         xCoordSetCallback(int _coord); //Not sure if this is right, don't usually use function pointers.
}


Or perhaps the variable shouldn't be set by the user at all! The reason to have functions that do this for you is to avoid confusion as to whether or not the developer using a library should do something or not. That's why almost all libraries use this method of abstraction and have several get and set functions.
Last edited on
I would create this helper:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct Coord {
    typedef short value_type;

    Coord() : x(), y() {}
    Coord( value_type x, value_type y ) : x( x ), y( y ) {}

    void move_delta( Coord c ) { move_delta( c.x, c.y ); }
    void move_delta( value_type dx, value_type dy ) {
        x += dx; y += dy;
    }

    value_type x;
    value_type y;
};


And then I'd go with something similar to computerquip's suggestion because you probably
want the map to trigger an event when the character moves to a particular location.
Topic archived. No new replies allowed.