WEBVTT

00:00.180 --> 00:00.980
Hello again.

00:00.990 --> 00:04.170
In this video, we are going to look at the game manager.

00:05.070 --> 00:08.190
We have implemented the basic features of our game.

00:08.460 --> 00:10.620
Obviously, there is still a lot more that we could add.

00:10.620 --> 00:15.210
But before we go any further, we need to think about the organization of our code.

00:15.930 --> 00:17.610
Our main() function is too long.

00:17.760 --> 00:22.110
Ideally, a function should fit into a single screen, so you can see all the code without having to do

00:22.110 --> 00:23.070
any scrolling.

00:23.520 --> 00:26.940
And also, there is a lot of code which is duplicated across the program.

00:27.690 --> 00:33.870
So we are going to step aside for a minute and refactor the code. And we are going to start off, in this

00:33.870 --> 00:40.050
video, by moving the code from the main() function into a new class which will manage the game.

00:42.730 --> 00:48.280
This class will have the game window as a data member, and also all the entities from the game.

00:48.850 --> 00:55.450
It will have a constructor, to start things off, and a run() member function, which will perform the game

00:55.450 --> 00:56.080
loop.

00:56.590 --> 00:59.330
There is also going to be a new feature, reset().

00:59.350 --> 01:04.390
So this will reinitialize the entities. So we can use that to allow the user to restart the game.

01:05.620 --> 01:08.570
And we are also going to allow the user to pause the game.

01:08.590 --> 01:11.270
So this means that the ball will appear to stop moving.

01:11.290 --> 01:14.170
The user cannot move the paddle across the screen, and so on.

01:15.040 --> 01:17.200
So the entities are not being updated.

01:17.320 --> 01:19.600
However, the entities are still redrawn.

01:19.630 --> 01:24.340
So if we cover up the game window and then uncover it, it will still look normal.

01:25.900 --> 01:29.500
We need to know what the game's current state is.

01:29.500 --> 01:35.200
So we are going to have a member for that. And we are going to use a class enum, which is another

01:35.200 --> 01:36.100
C++11 feature.

01:37.210 --> 01:42.940
In the class definition, we need to include the headers for all the entities, and also the constants.

01:43.690 --> 01:49.240
Then we have all the members, so we have the game window, the background and so on. And we are using

01:49.240 --> 01:50.920
in-place initialization.

01:51.460 --> 01:57.100
And we can do this because all these constants are constant expressions, they are constexpr. If they

01:57.100 --> 01:59.050
were just normal const, we could not do this.

02:00.040 --> 02:05.860
So this means that when we create an object of game, then by default, game window will have these dimensions

02:05.860 --> 02:10.210
and that title, the ball will have these dimensions and so on.

02:12.950 --> 02:20.120
You will notice that I had to change this to a C string literal and not a C++ string, because C++ strings

02:20.120 --> 02:23.570
cannot be constexpr. At least, not in this version of C++.

02:24.530 --> 02:30.350
And we also need to have the vector initialized separately, because vectors are not constexpr either.

02:30.560 --> 02:31.580
Or, not yet.

02:33.020 --> 02:38.060
Then we have our class enum with the game's states, and then we have the member.

02:38.150 --> 02:44.630
So initially, we assume that the game is going to be running. And then we have the declaration of the

02:44.630 --> 02:45.650
member functions.

02:48.870 --> 02:50.460
In the game constructor,

02:50.460 --> 02:56.910
we do not need to provide an initialization list, because the class already has sensible initial values.

02:57.390 --> 03:01.560
If we did put anything in here, it would just override the default values.

03:01.560 --> 03:03.450
But we do not need to do that.

03:03.960 --> 03:11.010
All we need to do, is to populate the vector of bricks, the same code as we had before, and to set the

03:11.010 --> 03:16.260
frame rate for the window. In the reset() member function,

03:16.440 --> 03:23.370
we want to restore all the bricks to their original position. So all the destroyed bricks will be drawn

03:23.370 --> 03:23.690
again.

03:23.700 --> 03:25.380
They will come back to life, if you like.

03:25.500 --> 03:28.500
And the easiest way to do that is just to draw everything again.

03:30.540 --> 03:33.690
And then we have the one member function with the game loop.

03:34.530 --> 03:39.450
I will come back to this in a minute. But the basic loop is the same.

03:39.450 --> 03:44.910
So we clear the screen, check for events. (Skip ahead a bit)

03:45.900 --> 03:48.030
Then we update all the entities.

03:48.300 --> 03:50.010
We handle collisions.

03:50.970 --> 03:53.280
We erase all the removed bricks.

03:53.760 --> 03:57.150
And then we draw the updated graphics.

03:57.270 --> 04:01.770
So that is all the same code that you have seen before, with just a couple of little extra features.

04:04.620 --> 04:08.430
The first one is that we only do the updates if the game state is not "paused".

04:09.400 --> 04:15.370
So we do not do any of this update, collision handling and erasing, but we do display the graphics.

04:17.340 --> 04:22.560
And then we have this code for the pause and reset. The reset is very simple: we just check for the

04:22.680 --> 04:26.610
user pressing the 'r' key, and then we call the reset() function.

04:28.000 --> 04:30.400
We check for the user pressing the 'p' key.

04:30.940 --> 04:36.040
If they press it when the game is running, it will pause it. And if they press the key again, then the game

04:36.130 --> 04:37.060
will resume.

04:37.630 --> 04:40.480
So we just invert the state of the game.

04:42.010 --> 04:47.080
There is a complication here, because if the user holds down the key, then it is going to send an event

04:47.080 --> 04:51.130
on every iteration, until the user releases the key.

04:51.580 --> 04:56.220
So we could have a situation where the user presses the key, and that pauses the game.

04:56.260 --> 04:57.490
Then they hold it down.

04:57.820 --> 05:03.430
The next iteration gets the key again, so it resumes the game. Then the next iteration pauses and

05:03.430 --> 05:03.960
so on.

05:03.970 --> 05:08.860
So we have this kind of "whipsaw" effect, and we want to avoid that.

05:09.250 --> 05:12.040
So we put in a check to see if the key has already been pressed.

05:12.550 --> 05:14.560
So that is the purpose of this variable.

05:15.100 --> 05:22.630
So initially, the key has not been pressed. And then, the first time, this variable will be false.

05:22.630 --> 05:29.230
So we go into this, and we invert the state of the game. And then we set the flag to true.

05:29.920 --> 05:34.650
And then the next time, if the user holds the key down, then this will be true.

05:34.660 --> 05:42.850
So we skip over this. And if the user releases the key, or presses some other key, then we go into here.

05:42.850 --> 05:44.680
And this will set the flag to false.

05:46.620 --> 05:49.230
And finally, in the main() function, this is now very simple.

05:49.290 --> 05:51.600
We just create an object of the game.

05:51.690 --> 05:52.610
The game manager.

05:52.620 --> 05:54.510
So this will initialize everything.

05:54.960 --> 05:59.010
And then we call the run() member function and that will start up the game loop.

05:59.310 --> 06:00.780
So that will keep on running.

06:00.840 --> 06:06.900
And when the game loop terminates, then this function call will return, and we exit the program.

06:14.490 --> 06:15.480
So, there we are.

06:17.340 --> 06:19.530
I am busy playing this game, rather badly!

06:20.580 --> 06:22.200
And then the phone rings.

06:23.250 --> 06:24.360
(Just put this over here)

06:25.650 --> 06:27.180
(I do not want anyone to know I'm playing this game!)

06:28.350 --> 06:28.910
(Okay)

06:30.040 --> 06:32.220
(The phone call is over) And you can see the window looks normal.

06:32.310 --> 06:37.290
We do not have any busy cursor, or black screen, or "window not responding" message.

06:38.610 --> 06:39.900
And then we can continue.

06:42.600 --> 06:43.290
And then...

06:47.040 --> 06:50.040
If I want to restart, then I just press the "r" key.

06:51.180 --> 06:52.650
And then all the bricks reappear.

06:53.040 --> 06:58.200
I suppose I should really make the ball go back to the initial position, and the paddle, but that would

06:58.200 --> 06:59.960
require some changes to the entity.

07:00.330 --> 07:04.830
But if you want to do that, if you want to make the ball and the paddle go back to the initial positions

07:04.830 --> 07:08.310
when the user resets the game, then that would be a useful exercise.

07:09.080 --> 07:10.440
Okay, so that is it for this video.

07:10.470 --> 07:11.340
I will see you next time.

07:11.340 --> 07:13.230
But until then, keep coding.
