Add Movable Player to Map

Pages: 12
I have just created a 15 x 20 map using a 2D-array. I am trying to add a movable player, but I can't figure out how. If at all possible, this is something I would like to do without having to add new header files outside of Code::Blocks existing set, use functions I haven't made myself, or use classes.

Does anyone think they could help me with this?

Here's the code so far:
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
32
33
34
35
36
37
38
39
#include <iostream>
#define MAP_ROWS 15
#define MAP_COLS 20

using namespace std;

int main()
{
    // char player = '@';
    char mapArray[MAP_ROWS][MAP_COLS] =
    {
        {'_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','|'}
    };

    for(int i = 0; i < MAP_ROWS; i++)
    {
        for(int j = 0; j < MAP_COLS; j++)
        {
            cout << mapArray[i][j];
        }
        cout << "\n";
    }

    return 0;
}
Last edited on
create a player structure which holds the player's x,y coordinates.

in the display loop, check if the current position is the players position.
if so, display player character, otherwise display map character
Thank you for the feedback, but how do I create a player structure to hold the x and y coordinates?
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#define MAP_ROWS 15
#define MAP_COLS 20

using namespace std;

// This defines a new type called Player
struct Player{
    int x;
    int y;
};


int main()
{
    // char player = '@';
    
    Player player;  // This creates an instance of the type Player named player
    player.x = 5;
    player.y = 6;
    char mapArray[MAP_ROWS][MAP_COLS] =
    {
        {'_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','|'}
    };

    for(int i = 0; i < MAP_ROWS; i++)
    {
        for(int j = 0; j < MAP_COLS; j++)
        {
            if( i == player.x  && j = player.y )
                cout << '@';
            else
                cout << mapArray[i][j];
        }
        cout << "\n";
    }

    return 0;
}


If you don't understand structures and classes yet, this may be jumping ahead for you a bit.

For something this simple, you could also do it by just having individual variables for the player's x and y coordinates rather than using a struct. just have something like: int plr_x = 5, plr_y = 6;
Last edited on
Alright, so a struct is like a class, is it?

Without using a struct, this is what I have so far:
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#define MAP_ROWS 15
#define MAP_COLS 20

using namespace std;

int main()
{
    int playerX = 0;
    int playerY = 0;
    char mapArray[MAP_ROWS][MAP_COLS] =
    {
        {'_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','|'}
    };

    cout << "Player Starting Position\n";
    cout << "X Coordinate (1 - 13): ";
    cin >> playerX;
    cout << "Y Coordinate (1 - 18): ";
    cin >> playerY;

    for(int i = 0; i < MAP_ROWS; i++)
    {
        for(int j = 0; j < MAP_COLS; j++)
        {
            if(playerX == i && playerY == j)
            {
                cout << '@';
            }
            else
            {
                cout << mapArray[i][j];
            }
        }
        cout << "\n";
    }

    return 0;
}


So how would I add player movement? Is this where things get tricky?
Last edited on
First, I'd break out the display code into a function. then in main have a loop where the player inputs movement commands and updates coordinates, then call the display function.
If I make the display code a function, then I have to drag int mapArray[MAP_ROWS][MAP_COLS]with it. That would make the map local to the function. Would that be a problem?
No problem. You can pass the array as an argument (arrays pass by reference by default) so overhead is minimal.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void DrawMap( map[] ); // prototype

int main()
{
    ...
    DrawMap( mapArray );
    ...
    
}

void DrawMap( map[] )
{
    //draw it here
}
I don't know what I'm doing wrong here:
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#define MAP_ROWS 15
#define MAP_COLS 20

using namespace std;

void displayMap(int x, int y, char mapArray)
{
    for(int i = 0; i < MAP_ROWS; i++)
    {
        for(int j = 0; j < MAP_COLS; j++)
        {
            if(x == i && y == j)
            {
                cout << '@';
            }
            else
            {
                cout << mapArray[i][j];
            }
        }
        cout << "\n";
    }
}

int main()
{
    int playerX = 0;
    int playerY = 0;
    char playerMove = ' ';

    char mapArray[MAP_ROWS][MAP_COLS] =
    {
        {'_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','|'}
    };

    cout << "Player Starting Position\n";
    cout << "X Coordinate (1 - 13): ";
    cin >> playerX;
    cout << "Y Coordinate (1 - 18): ";
    cin >> playerY;

    displayMap(playerX, playerY, mapArray[MAP_ROWS][MAP_COLS]);

    /*
    cout << "Choose a direction to move (U, D, L, R): ";

    while(1 > 0)
    {
        cin >> playerMove;

        switch(playerMove)
        {
            case 'U':
                playerY++;
                break;
            case 'D':
                playerY--;
                break;
            case 'L':
                playerX--;
                break;
            case 'R':
                playerX++;
                break;
            default:
                return 0;
        }
    }
    */

    return 0;
}
line 7 should be: void displayMap(int x, int y, char mapArray[] )

without the [] it thinks it's just receiving a regular char variable.

line 57 can just be displayMap( playerX, playerY, mapArray );
Well are you familiar with using a "keyListener"?

I think that's something you should familiarize yourself with.
I'm looking for help, not smart comments.
lol... Sherre wasn't being a smart ass. He/She was actually trying to help. A keyListener is a method for trapping and translating keyboard input.
D'oh! My apologies sherre02, my ignorance was showing.
So, something is starting to happen now. The problem is getting it to stay on one grid. Any ideas on how I can get it to stay on one grid, rather than repeating the grid over and over?
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#define MAP_ROWS 15
#define MAP_COLS 20

using namespace std;

void displayMap(int x, int y, char mapArray[MAP_ROWS][MAP_COLS])
{
    for(int i = 0; i < MAP_ROWS; i++)
    {
        for(int j = 0; j < MAP_COLS; j++)
        {
            if(x == i && y == j)
            {
                cout << '@';
            }
            else
            {
                cout << mapArray[i][j];
            }
        }
        cout << "\n";
    }
}

int main()
{
    int playerX = 0;
    int playerY = 0;
    char playerMove = ' ';

    char mapArray[MAP_ROWS][MAP_COLS] =
    {
        {'_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
        {'|','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','|'}
    };

    cout << "Player Starting Position\n";
    cout << "X Coordinate (1 - 13): ";
    cin >> playerX;
    cout << "Y Coordinate (1 - 18): ";
    cin >> playerY;

    displayMap(playerX, playerY, mapArray);


    cout << "Choose a direction to move (U, D, L, R): ";

    while(1 > 0)
    {
        cin >> playerMove;

        switch(playerMove)
        {
            case 'U':
                playerX--;
                break;
            case 'D':
                playerX++;
                break;
            case 'L':
                playerY--;
                break;
            case 'R':
                playerY++;
                break;
            default:
                return 0;
        }

    displayMap(playerX, playerY, mapArray);

    }

    return 0;
}
Last edited on
Does anyone know how to keep the output on one grid?

Edit:
Okay, I added this to line 84:
1
2
cout << string(50, '\n');
displayMap(playerX, playerY, mapArray);

This sort of makes it look like it's staying on one grid. It's very flickery though and not really what I am trying to achieve as it's not actually staying on the one grid. Any suggestions?
Last edited on
Here's a nice and explicit tutorial:

http://www.youtube.com/watch?v=kfRjvvgjTNQ

It helped me out back when i wanted to do the same thing.
Is there a reason why you are using the console for an interactive game? I can understand if it's for a homework assignment, but if not then I have to strongly suggest to move onto a graphical library. They certainly aren't harder than writing a console game (by far). They're much easier than they seem.

Start with either SFML 2.1 or SDL 2.0. After that then you can move onto OpenGL or Direct3D.

I personally prefer SDL 2.0. It's written in C and is a bit more low-level than SFML, but with that simplicity you get a very small executable size (making it suitable for Android and iOS apps). It's fairly API agnostic, and you can get an OpenGL or Direct3D context relatively easily.

SFML 2.1 is written in C++ and is a bit more high-level, and it's written in C++ (which sounds like a good thing, but that's not always true). The executable size is bigger, but it trades off with providing a nice interface for the programmer. It isn't very API agnostic though (centered around OpenGL), and afaik it doesn't easily allow creation of modern OpenGL contexts. I haven't seen anyone actually create a Direct3D based application with it and the creator doesn't have any intention of supporting one (http://en.sfml-dev.org/forums/index.php?topic=3719.0 ).
Last edited on
Thank you for the advice Avilius.

I am using a console application because it is what I am familiar with. I wanted to see if I could make a map with a movable player that can interact with other objects on the map. It shouldn't be necessary to involve a graphics library for something like this, but maybe I'm underestimating the difficulty of implementing my ideas. Anyway, If it is feasible, I would like to stick with using a console application for now.

If it's definitely not, then I will look into graphics libraries. For two dimensional interactivity, which is all I would be interested in, would you recommend SFML 2.1 or SDL 2.0?
I think trying to set up and use a graphics library could be a bit overwhelming, and distracting if you're just doing this as a learning exercise.

As to your question, are you trying to figure out how to move your character around the map without redrawing the map each frame and scrolling the last frame off the top of the console?
Pages: 12