Add Movable Player to Map

Pages: 12
Nov 1, 2014 at 9:16pm
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 Nov 2, 2014 at 12:50pm
Nov 1, 2014 at 9:30pm
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
Nov 1, 2014 at 9:43pm
Thank you for the feedback, but how do I create a player structure to hold the x and y coordinates?
Nov 1, 2014 at 9:49pm
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 Nov 1, 2014 at 9:55pm
Nov 1, 2014 at 10:32pm
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 Nov 1, 2014 at 10:35pm
Nov 1, 2014 at 11:01pm
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.
Nov 1, 2014 at 11:12pm
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?
Nov 1, 2014 at 11:21pm
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
}
Nov 1, 2014 at 11:33pm
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;
}
Nov 1, 2014 at 11:37pm
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 );
Nov 1, 2014 at 11:40pm
Well are you familiar with using a "keyListener"?

I think that's something you should familiarize yourself with.
Nov 1, 2014 at 11:41pm
I'm looking for help, not smart comments.
Nov 1, 2014 at 11:49pm
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.
Nov 1, 2014 at 11:59pm
D'oh! My apologies sherre02, my ignorance was showing.
Nov 2, 2014 at 12:02am
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 Nov 2, 2014 at 12:26am
Nov 2, 2014 at 9:31am
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 Nov 2, 2014 at 12:49pm
Nov 2, 2014 at 1:38pm
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.
Nov 2, 2014 at 4:10pm
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 Nov 2, 2014 at 4:11pm
Nov 2, 2014 at 7:14pm
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?
Nov 2, 2014 at 7:25pm
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