Updating Unnecessarily (efficiency problem)

closed account (ypS8AqkS)
Yo wassup guys, I've just recently started learning C++ (I started 2 days ago, actually) and I was wondering if any of you would be willing to guide me towards the right direction.

I decided to try and make a little text game but ran into some inefficiency problems..

Relevant Variables ** excluding the map, as it is too long.
1
2
3
4
5
bool gameRunning = true;
int gameSpeed = 100;

int x = 1;  // Start off at coordinates 1,1
int y = 1;


Movement handling

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
void handleMovement()
{
	if (GetAsyncKeyState(VK_DOWN))
	{
		int y2 = y + 1;
		if (gameMap[y2][x] == ' ')
		{
			gameMap[y][x] = ' ';
			y++;
			gameMap[y][x] = '@';
		}
	}

	if (GetAsyncKeyState(VK_UP))
	{
		int y2 = y - 1;
		if (gameMap[y2][x] == ' ')
		{
			gameMap[y][x] = ' ';
			y--;
			gameMap[y][x] = '@';
		}
	}

	if (GetAsyncKeyState(VK_RIGHT))
	{
		int x2 = x + 1;
		if (gameMap[y][x2] == ' ')
		{
			gameMap[y][x] = ' ';
			x++;
			gameMap[y][x] = '@';
		}
	}

	if (GetAsyncKeyState(VK_LEFT))
	{
		int x2 = x - 1;
		if (gameMap[y][x2] == ' ')
		{
			gameMap[y][x] = ' ';
			x--;
			gameMap[y][x] = '@';
		}
	}
}


Main
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
int main()
{
	while (gameRunning == true)
	{
		system("cls");

     // Constantly and unnecessarily keeps regenerating the map,
     // I'm trying to make it so it only generates the map
     // itself once, and updates it only when the character moves.

		for (int yAxis = 0; yAxis<25; yAxis++)
		{
			cout << gameMap[yAxis] << endl;
		}

		system("pause>nul"); // stops constant flickering

		handleMovement();

		Sleep(gameSpeed);
	}

	system("cls");
	cout << "GAME OVER";

	return 0;
	}


As the comment on the previous code points out, there is a lot of unnecessary map updating going on, which I tried to solve with the following code:

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
void clearScreen()
{
	system("cls");
}

void stopMapFlickering()
{
	system("pause>nul");
}

void generateMap()
{
	for (int yAxis = 0; yAxis < 25; yAxis++)
	{
		cout << gameMap[yAxis] << endl;
	}
}


int main()
{
	clearScreen();
	generateMap();
	stopMapFlickering();


	while (gameRunning == true)
	{
		handleMovement();
		Sleep(gameSpeed);
	}

	return 0;
}


I thought something like this would work, but it makes it so I can't move for some reason.

Any help would be much appreciated. Thanks
You do move your character, but do not see it, as you do not ever redraw screen.
closed account (ypS8AqkS)
Ah, I see.

Well, is there any way to make it so it only update's the character's movement, instead of regenerating the entire map? , or at least get rid of that awful flickering effect..
Last edited on
When character moves, set bool variable updated to true. In main loop check it and if it is true, redraw map and set that variable to false.
closed account (ypS8AqkS)
The following code snippet still causes the map to flicker every time a player moves:

Movement Handling
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
bool handleMovement()
{
	bool needsUpdate = false;
	if (GetAsyncKeyState(VK_DOWN))
	{
		int y2 = y + 1;
		if (gameMap[y2][x] == ' ')
		{
			gameMap[y][x] = ' ';
			y++;
			gameMap[y][x] = '@';
			needsUpdate = true;
		}
	}

	if (GetAsyncKeyState(VK_UP))
	{
		int y2 = y - 1;
		if (gameMap[y2][x] == ' ')
		{
			gameMap[y][x] = ' ';
			y--;
			SetConsoleTextAttribute(h, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
			gameMap[y][x] = '@';
			needsUpdate = true;
		}
	}

	if (GetAsyncKeyState(VK_RIGHT))
	{
		int x2 = x + 1;
		if (gameMap[y][x2] == ' ')
		{
			gameMap[y][x] = ' ';
			x++;
			gameMap[y][x] = '@';
			needsUpdate = true;
		}
	}

	if (GetAsyncKeyState(VK_LEFT))
	{
		int x2 = x - 1;
		if (gameMap[y][x2] == ' ')
		{
			gameMap[y][x] = ' ';
			x--;
			gameMap[y][x] = '@';
			needsUpdate = true;
		}
	}

	return needsUpdate;
}


Main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{

	clearScreen();
	generateMap();
	stopMapFlickering();

	while (gameRunning == true)
	{
		bool mapNeedsUpdate = handleMovement();
		if (mapNeedsUpdate)
		{
			clearScreen();
			generateMap();
		}

		Sleep(gameSpeed);
	}
	return 0;
}


I am trying to make it so it only updates the player's location when a player moves, without the extra step of having to regenerate the entire map(only update the player's new location), or if that is impossible, is there at least some hacky way of getting around that constant flickering? (like generating the map fast enough that it is impossible to perceive).
Last edited on
First of all, usage of stream output for games is bad choice in general. Second is that system calls are terribly slow compared to other possibilities.

To get adequate results, you will need to eschew standard IO (which operates using stream ideology and is not suited for games) and manipulate console window directly using API calls.
For example use second snippet shown on next link to clear window:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682022%28v=vs.85%29.aspx

Also make yourself familiar with other console API and use it. You will probably have to write helper functions for things like drawing map on screen, etc.

Alternatively, use library which makes those things way easier to do. Like pdcurses.
Topic archived. No new replies allowed.