1
00:00:01,003 --> 00:00:02,008
- [Instructor] Hi, this video is

2
00:00:02,008 --> 00:00:05,002
Building the levelManager Class.

3
00:00:05,002 --> 00:00:07,008
In the previous video, we
learned about designing levels.

4
00:00:07,008 --> 00:00:12,006
In this video, we're going
to code LevelManager.h

5
00:00:12,006 --> 00:00:15,007
and LevelManager.cpp.

6
00:00:15,007 --> 00:00:17,003
It will take several phases of coding

7
00:00:17,003 --> 00:00:19,008
to make our level designs work.

8
00:00:19,008 --> 00:00:21,003
The first thing we will do

9
00:00:21,003 --> 00:00:23,008
is code the LevelManager header file.

10
00:00:23,008 --> 00:00:25,006
This will allow us to look at and discuss

11
00:00:25,006 --> 00:00:27,004
the member variables and functions

12
00:00:27,004 --> 00:00:30,000
that will be in the LevelManager Class.

13
00:00:30,000 --> 00:00:34,001
Next, we will code the
LevelManager.cpp file

14
00:00:34,001 --> 00:00:37,004
which will have all the
function definitions in it.

15
00:00:37,004 --> 00:00:39,009
As this is a long file,
we will break it up

16
00:00:39,009 --> 00:00:43,003
into several sections to
code and discuss them.

17
00:00:43,003 --> 00:00:45,009
Once the LevelManager Class is complete,

18
00:00:45,009 --> 00:00:47,008
we will add an instance of it

19
00:00:47,008 --> 00:00:50,001
to the game engine, Engine Class.

20
00:00:50,001 --> 00:00:52,000
We will also add a new function

21
00:00:52,000 --> 00:00:54,002
to the Engine Class
loadLevel which we can call

22
00:00:54,002 --> 00:00:58,004
from the update function
whenever a new level is required.

23
00:00:58,004 --> 00:01:00,007
The loadLevel function will not only

24
00:01:00,007 --> 00:01:03,009
use the LevelManager instance
to load the appropriate level,

25
00:01:03,009 --> 00:01:06,003
but it will also take care of aspects

26
00:01:06,003 --> 00:01:08,001
such as spawning the player characters

27
00:01:08,001 --> 00:01:10,004
and preparing the clock.

28
00:01:10,004 --> 00:01:12,008
As already mentioned,
let's get an overview

29
00:01:12,008 --> 00:01:16,004
of LevelManager by coding
the LevelManager.h file.

30
00:01:16,004 --> 00:01:20,002
Create a .h file is always
right click header files

31
00:01:20,002 --> 00:01:24,004
in the solution explorer
and select add new item.

32
00:01:24,004 --> 00:01:27,007
Click headerfile.h, and
then, in the name field,

33
00:01:27,007 --> 00:01:29,009
type LevelManager.

34
00:01:29,009 --> 00:01:32,003
Lastly, click Add.

35
00:01:32,003 --> 00:01:34,000
We are now ready to code the header file

36
00:01:34,000 --> 00:01:36,004
for the LevelManager Class.

37
00:01:36,004 --> 00:01:39,004
Now add this highlighted code to the file.

38
00:01:39,004 --> 00:01:42,000
It consists of necessary
include directives

39
00:01:42,000 --> 00:01:44,000
and private variables.

40
00:01:44,000 --> 00:01:46,003
Here we're adding an include directive

41
00:01:46,003 --> 00:01:49,006
called SFML Graphics.hpp.

42
00:01:49,006 --> 00:01:54,002
Then, we are using namespace
sf and namespace std.

43
00:01:54,002 --> 00:01:56,005
In the LevelManager Class,

44
00:01:56,005 --> 00:01:59,005
these are the various private variables.

45
00:01:59,005 --> 00:02:04,002
The code first declares
Vector2im_LevelSize

46
00:02:04,002 --> 00:02:07,000
to hold two integer values
that will hold the horizontal

47
00:02:07,000 --> 00:02:11,000
and vertical number of tiles
that the current map contains.

48
00:02:11,000 --> 00:02:15,007
Vector2fm_StartPosition
contains the coordinates

49
00:02:15,007 --> 00:02:19,005
in the world where Bob and
Thomas should be spawned.

50
00:02:19,005 --> 00:02:22,004
Note that this is not a
tile position relatable

51
00:02:22,004 --> 00:02:25,000
to m_LevelSize units,

52
00:02:25,000 --> 00:02:29,002
but a horizontal and vertical
pixel position in the level.

53
00:02:29,002 --> 00:02:33,006
The m_TimeModifier member
variable is a float

54
00:02:33,006 --> 00:02:36,001
that will be used to
multiply the time available

55
00:02:36,001 --> 00:02:37,006
in the current level.

56
00:02:37,006 --> 00:02:39,009
The reason we want to do
this is so that by changing,

57
00:02:39,009 --> 00:02:41,007
decreasing this value

58
00:02:41,007 --> 00:02:43,008
we will shorten the
time available each time

59
00:02:43,008 --> 00:02:46,001
the player attempts the same level.

60
00:02:46,001 --> 00:02:48,007
As an example, if the
player gets 60 seconds

61
00:02:48,007 --> 00:02:51,001
for the first time they attempt level one

62
00:02:51,001 --> 00:02:55,002
then, 60 multiplied by
one is of course 60.

63
00:02:55,002 --> 00:02:57,004
When the player completes all the levels

64
00:02:57,004 --> 00:03:00,001
and comes back to level
one for the second time,

65
00:03:00,001 --> 00:03:04,004
m_TimeModifier will have
been reduced by 10%.

66
00:03:04,004 --> 00:03:08,003
Then, when the time available
is multiplied by 0.9,

67
00:03:08,003 --> 00:03:10,006
the amount of time available to the player

68
00:03:10,006 --> 00:03:12,003
will be 54 seconds.

69
00:03:12,003 --> 00:03:14,007
This is 10% less than 60.

70
00:03:14,007 --> 00:03:17,000
The game will get steadily harder.

71
00:03:17,000 --> 00:03:21,005
The float variable m_Base
time limit holds the original

72
00:03:21,005 --> 00:03:24,006
unmodified time limit we
have just been discussing.

73
00:03:24,006 --> 00:03:28,000
You can probably guess that m_CurrentLevel

74
00:03:28,000 --> 00:03:31,006
will hold the current level
number that is being played.

75
00:03:31,006 --> 00:03:36,002
The int NUM_Levels constant
will be used to flag

76
00:03:36,002 --> 00:03:39,003
when it is appropriate to
go back to level one again

77
00:03:39,003 --> 00:03:44,002
and reduce the value of m_TimeModifier.

78
00:03:44,002 --> 00:03:45,009
Next, add this highlighted code

79
00:03:45,009 --> 00:03:50,000
which consists public variables
and function declarations.

80
00:03:50,000 --> 00:03:51,006
Let's go through it.

81
00:03:51,006 --> 00:03:54,009
Notice that there are
two constant int members.

82
00:03:54,009 --> 00:03:58,008
TILE_size is a useful
constant to remind us

83
00:03:58,008 --> 00:04:00,009
that each tile in the sprite sheet

84
00:04:00,009 --> 00:04:04,007
is 50 pixels wide and 50 pixels high.

85
00:04:04,007 --> 00:04:08,009
VERTS_IN_QUAD is a useful constant

86
00:04:08,009 --> 00:04:11,007
to make our manipulation of a vertex array

87
00:04:11,007 --> 00:04:13,005
less error prone.

88
00:04:13,005 --> 00:04:16,005
There are, in fact,
four vertices in a quad.

89
00:04:16,005 --> 00:04:18,007
Now we can't forget it.

90
00:04:18,007 --> 00:04:22,005
The get TimeLimit, get
StartPosition, get LevelSize,

91
00:04:22,005 --> 00:04:25,007
and get CurrentLevel functions
are simple getter functions

92
00:04:25,007 --> 00:04:28,004
that return the current value

93
00:04:28,004 --> 00:04:31,007
of the private member variables

94
00:04:31,007 --> 00:04:35,001
we declared in the previous block of code.

95
00:04:35,001 --> 00:04:38,009
A function that deserves a
closer look is nextLevel.

96
00:04:38,009 --> 00:04:40,004
This function receives
a vertex array reference

97
00:04:40,004 --> 00:04:42,000
just like we use in the Zombie Arena game.

98
00:04:42,000 --> 00:04:44,005
The function can then
work on the vertex array

99
00:04:44,005 --> 00:04:46,000
and all the changes will be present

100
00:04:46,000 --> 00:04:48,006
in the vertex array from the calling code.

101
00:04:48,006 --> 00:04:51,007
The next level function
returns a pointer to a pointer

102
00:04:51,007 --> 00:04:53,002
which means we can return an address

103
00:04:53,002 --> 00:04:54,003
that is the first segment

104
00:04:54,003 --> 00:04:57,006
of a two dimensional array of int values.

105
00:04:57,006 --> 00:05:00,001
We will be building a
two dimensional array

106
00:05:00,001 --> 00:05:04,001
of int values that will represent
the layout of each level.

107
00:05:04,001 --> 00:05:06,006
Of course, these int values will be read

108
00:05:06,006 --> 00:05:09,004
from the level designed text files.

109
00:05:09,004 --> 00:05:13,004
Now we'll code the LevelManager.cpp file.

110
00:05:13,004 --> 00:05:16,005
Right click Source Files
in the solution explorer,

111
00:05:16,005 --> 00:05:17,009
and select add new item.

112
00:05:17,009 --> 00:05:22,003
In the add new item
window, select C++ file,

113
00:05:22,003 --> 00:05:24,008
and then rename the file to LevelManager.

114
00:05:24,008 --> 00:05:26,005
Lastly, click Add.

115
00:05:26,005 --> 00:05:29,001
We are now ready to code the .cpp file

116
00:05:29,001 --> 00:05:31,006
for the LevelManager Class.

117
00:05:31,006 --> 00:05:33,009
As this is quite a long
class, we'll break it up

118
00:05:33,009 --> 00:05:36,003
to discuss it in six chunks.

119
00:05:36,003 --> 00:05:38,008
The first five will cover
the nextLevel function,

120
00:05:38,008 --> 00:05:41,001
and the sixth all the rest.

121
00:05:41,001 --> 00:05:43,002
Add this highlighted code.

122
00:05:43,002 --> 00:05:45,009
Here we are adding Shows
Include Directives,

123
00:05:45,009 --> 00:05:50,002
and the first of five part
of the nextLevel function.

124
00:05:50,002 --> 00:05:52,002
After the include directives,

125
00:05:52,002 --> 00:05:56,007
the code initializes m_LevelSize.x and

126
00:05:56,007 --> 00:05:59,009
m_LevelSIze.y to zero.

127
00:05:59,009 --> 00:06:03,005
Next, m_CurrentLevel is incremented.

128
00:06:03,005 --> 00:06:05,003
The if statement that follows checks

129
00:06:05,003 --> 00:06:10,007
whether m_CurrentLevel is
greater than NUM_Levels.

130
00:06:10,007 --> 00:06:14,003
If it is, m_CurrentLevel
is sent back to zero,

131
00:06:14,003 --> 00:06:19,002
and m_TimeModifier is reduced by 0.1f

132
00:06:19,002 --> 00:06:22,002
in order to shorten the
time allowed for all levels.

133
00:06:22,002 --> 00:06:25,000
The code then switches
based on the value held by

134
00:06:25,000 --> 00:06:27,003
m_CurrentLevel.

135
00:06:27,003 --> 00:06:30,002
Each case statement initializes
the name of the text file

136
00:06:30,002 --> 00:06:32,001
which holds the level design.

137
00:06:32,001 --> 00:06:34,004
And the starting position
for Thomas and Bob,

138
00:06:34,004 --> 00:06:35,002
as well as m_BaseTimeLimit

139
00:06:35,002 --> 00:06:38,007
which is the unmodified time limit

140
00:06:38,007 --> 00:06:40,008
for the level in question.

141
00:06:40,008 --> 00:06:44,000
Now add the second part
of the nextLevel function.

142
00:06:44,000 --> 00:06:45,004
Add this highlighted code

143
00:06:45,004 --> 00:06:47,004
immediately after the previous code.

144
00:06:47,004 --> 00:06:49,004
We'll go through it in detail.

145
00:06:49,004 --> 00:06:53,007
First, we declare an if stream
object called input file

146
00:06:53,007 --> 00:06:55,006
which opens a stream to the file name

147
00:06:55,006 --> 00:06:57,007
contained in leveltoLoad.

148
00:06:57,007 --> 00:07:00,001
The code loops through
each line of the file

149
00:07:00,001 --> 00:07:03,006
using get line, but doesn't
record any of its content.

150
00:07:03,006 --> 00:07:06,009
All it does is count the
number of lines by incrementing

151
00:07:06,009 --> 00:07:09,006
m_LevelSize.y.

152
00:07:09,006 --> 00:07:12,000
After the while loop,
the width of the level

153
00:07:12,000 --> 00:07:17,003
is saved in m_LevelSize.x using s.length.

154
00:07:17,003 --> 00:07:20,007
This implies that the level
length of all the lines

155
00:07:20,007 --> 00:07:23,000
must be the same or we
would run into trouble.

156
00:07:23,000 --> 00:07:24,007
At this point, we know and have saved

157
00:07:24,007 --> 00:07:26,009
the length and width of the current level

158
00:07:26,009 --> 00:07:29,008
in m_LevelSize.

159
00:07:29,008 --> 00:07:32,008
Now add the third part of
the next level function.

160
00:07:32,008 --> 00:07:36,003
Add this code immediately
after the previous code.

161
00:07:36,003 --> 00:07:39,003
Here, we first, we clear Input file

162
00:07:39,003 --> 00:07:41,003
using its clear function.

163
00:07:41,003 --> 00:07:45,009
The seek g function called with
the zero ios beg parameters

164
00:07:45,009 --> 00:07:49,008
resets the string back to
before the first character.

165
00:07:49,008 --> 00:07:53,008
Next, we declare a pointer to
a pointer called arrayLevel.

166
00:07:53,008 --> 00:07:56,008
Note that this is done
on the free store or heap

167
00:07:56,008 --> 00:07:58,008
using the new key word.

168
00:07:58,008 --> 00:08:00,009
Once we have initialized
this two dimensional array,

169
00:08:00,009 --> 00:08:03,007
we'll be able to return its
address to the calling code,

170
00:08:03,007 --> 00:08:06,000
and it will persist
until we either delete it

171
00:08:06,000 --> 00:08:08,002
or the game is closed.

172
00:08:08,002 --> 00:08:14,004
This is for loop loops from
zero to m-LevelSize.y minus one.

173
00:08:14,004 --> 00:08:17,009
In each pass, it adds a
new array of int values

174
00:08:17,009 --> 00:08:23,005
to the heap to match the
value of m_LevelSize.x.

175
00:08:23,005 --> 00:08:27,001
We now have a perfectly
configured for the current level

176
00:08:27,001 --> 00:08:27,009
two dimensional array.

177
00:08:27,009 --> 00:08:30,008
The only problem is that
there's nothing in it.

178
00:08:30,008 --> 00:08:34,003
Next, we add the fourth part
of the nextLevel function.

179
00:08:34,003 --> 00:08:37,005
Add this code immediately
after the previous code.

180
00:08:37,005 --> 00:08:41,002
First, the code initializes
a string called row

181
00:08:41,002 --> 00:08:44,006
which will hold one row of
the level design at the time.

182
00:08:44,006 --> 00:08:48,000
We also declare and
initialize and int called y

183
00:08:48,000 --> 00:08:50,003
that will help us count the rows.

184
00:08:50,003 --> 00:08:53,007
The while loop executes
repeatedly until input file

185
00:08:53,007 --> 00:08:55,006
gets past the last row.

186
00:08:55,006 --> 00:08:58,006
Inside the while loop, there is a for loop

187
00:08:58,006 --> 00:09:01,000
which goes through each
character of the current row

188
00:09:01,000 --> 00:09:04,004
and stores it in the two
dimensional array, arrayLevel.

189
00:09:04,004 --> 00:09:07,001
Notice that we assess
exactly the right element

190
00:09:07,001 --> 00:09:09,005
of the two dimensional array

191
00:09:09,005 --> 00:09:11,009
with arrayLevel, array of y, and x.

192
00:09:11,009 --> 00:09:16,000
The a to i function
converts char val to int.

193
00:09:16,000 --> 00:09:18,002
This is what is required because we have

194
00:09:18,002 --> 00:09:21,003
a two dimensional array for int not char.

195
00:09:21,003 --> 00:09:26,000
Over here, we increment y
and lastly close the file.

196
00:09:26,000 --> 00:09:29,004
Now add the fifth part of
the nextLevel function.

197
00:09:29,004 --> 00:09:32,002
Add the code right after the previous one.

198
00:09:32,002 --> 00:09:34,004
This is entire highlighted code.

199
00:09:34,004 --> 00:09:37,000
Just after close the file.

200
00:09:37,000 --> 00:09:39,003
Although this is the
longest section of code

201
00:09:39,003 --> 00:09:42,000
from the five sections we
divided nextLevel into,

202
00:09:42,000 --> 00:09:44,000
it is also the most straight forward.

203
00:09:44,000 --> 00:09:47,002
What happens is that the
nested for loop loops

204
00:09:47,002 --> 00:09:50,002
from zero through to the
width and height of the level.

205
00:09:50,002 --> 00:09:52,009
For each position in the
array, four vertices are

206
00:09:52,009 --> 00:09:56,001
put into vertex array
and for text coordinates

207
00:09:56,001 --> 00:09:58,001
are assigned from the sprite sheet.

208
00:09:58,001 --> 00:10:00,006
The positions of the vertices
and texture coordinates

209
00:10:00,006 --> 00:10:03,005
are calculated using the
current vertex available

210
00:10:03,005 --> 00:10:09,000
the tile size and VERTS_IN_QUAD constants.

211
00:10:09,000 --> 00:10:11,009
At the end of each loop
of the inner for loop,

212
00:10:11,009 --> 00:10:16,002
current vertex is
increased by VERTS_IN_QUAD

213
00:10:16,002 --> 00:10:19,000
moving nicely onto the next tile.

214
00:10:19,000 --> 00:10:21,007
The important thing to remember
about this vertex array

215
00:10:21,007 --> 00:10:23,007
is that it was passed into
nextLevel by reference

216
00:10:23,007 --> 00:10:26,006
therefore the vertex
array will be available

217
00:10:26,006 --> 00:10:28,000
in the calling code.

218
00:10:28,000 --> 00:10:31,003
We will call nextLevel from
the code in the Engine Class.

219
00:10:31,003 --> 00:10:32,009
Once this function has been called,

220
00:10:32,009 --> 00:10:34,007
the Engine Class will have a vertex array

221
00:10:34,007 --> 00:10:36,007
to represent the level graphically.

222
00:10:36,007 --> 00:10:39,004
A two dimensional array of int values

223
00:10:39,004 --> 00:10:41,009
as a numerical representation
of all the platforms

224
00:10:41,009 --> 00:10:44,002
and obstacles in the level.

225
00:10:44,002 --> 00:10:46,000
The last part is remaining now.

226
00:10:46,000 --> 00:10:48,002
You have to add this
highlighted code after the end

227
00:10:48,002 --> 00:10:50,004
of nextLevel function.

228
00:10:50,004 --> 00:10:52,007
Here we are adding rest of the functions

229
00:10:52,007 --> 00:10:54,006
from LevelManager Class.

230
00:10:54,006 --> 00:10:58,004
These LevelManager functions
are all simple getter functions

231
00:10:58,004 --> 00:11:00,008
but do take the time
to familiarize yourself

232
00:11:00,008 --> 00:11:04,003
with what private value is
returned by which function.

233
00:11:04,003 --> 00:11:06,009
Now that the LevelManager
Class is complete

234
00:11:06,009 --> 00:11:09,001
we can move on to using it.

235
00:11:09,001 --> 00:11:12,006
We will code another function
in the Engine Class to do so.

236
00:11:12,006 --> 00:11:14,000
Cool!

237
00:11:14,000 --> 00:11:15,004
In this video, we have learned

238
00:11:15,004 --> 00:11:17,005
building the LevelManager Class.

239
00:11:17,005 --> 00:11:21,001
Next up, we'll code
the loadLevel function.

