1
00:00:01,004 --> 00:00:05,004
- Hi, welcome to Building
the Playable Character Class.

2
00:00:05,004 --> 00:00:07,007
Previously, we looked at abstract classes,

3
00:00:07,007 --> 00:00:10,006
virtual and pure virtual functions.

4
00:00:10,006 --> 00:00:13,000
In this video, we're
going to look at coding

5
00:00:13,000 --> 00:00:17,008
Playable Character.h and
Playable Character.cpp.

6
00:00:17,008 --> 00:00:20,002
Now that we know the
basics about inheritance,

7
00:00:20,002 --> 00:00:22,009
polymorphism, and pure virtual functions,

8
00:00:22,009 --> 00:00:24,008
let's put them to use.

9
00:00:24,008 --> 00:00:26,009
We will build a Playable Character Class

10
00:00:26,009 --> 00:00:28,009
that has the vast majority
of the functionality

11
00:00:28,009 --> 00:00:32,002
that any character from
our game is going to need.

12
00:00:32,002 --> 00:00:35,008
It will have one pure virtual
function, handle input.

13
00:00:35,008 --> 00:00:38,000
The handle input function
will need to be quite

14
00:00:38,000 --> 00:00:41,003
different in the sub-classes,
this makes sense,

15
00:00:41,003 --> 00:00:44,009
as Playable Character will
have a pure virtual function.

16
00:00:44,009 --> 00:00:46,008
It will be an abstract class,

17
00:00:46,008 --> 00:00:49,002
and no objects of it, will be possible.

18
00:00:49,002 --> 00:00:52,001
We will then build the both
Thomas and Bob Classes,

19
00:00:52,001 --> 00:00:54,001
which will inherit from
Playable Character,

20
00:00:54,001 --> 00:00:56,006
implement the definition of
the pure virtual function,

21
00:00:56,006 --> 00:00:59,006
and allow us to instantiate
Bob and Thomas objects

22
00:00:59,006 --> 00:01:02,001
in our game.

23
00:01:02,001 --> 00:01:05,008
Let's start with coding
Playable Character.h

24
00:01:05,008 --> 00:01:08,006
Right click Header Files
in the Solution Explorer,

25
00:01:08,006 --> 00:01:11,001
and select, Add New Item.

26
00:01:11,001 --> 00:01:15,002
In the Add New Item window,
click Header File.h,

27
00:01:15,002 --> 00:01:18,007
and then, in the name field,
type Playable Character.

28
00:01:18,007 --> 00:01:22,003
So, now the name is Playable Character.h.

29
00:01:22,003 --> 00:01:24,004
Lastly, click the Add button.

30
00:01:24,004 --> 00:01:26,002
We are now ready to code the Header File,

31
00:01:26,002 --> 00:01:28,009
for the Playable Character Class.

32
00:01:28,009 --> 00:01:31,005
Add this highlighted code in the file.

33
00:01:31,005 --> 00:01:34,007
As usual, when creating a
class, we will start off with

34
00:01:34,007 --> 00:01:37,002
the Header File, that will
contain the member variables,

35
00:01:37,002 --> 00:01:39,004
and function declarations.

36
00:01:39,004 --> 00:01:42,002
What is new, is that in this
class, we will declare some

37
00:01:42,002 --> 00:01:44,005
protected member variables.

38
00:01:44,005 --> 00:01:47,001
Remember, that protected
variables can be used,

39
00:01:47,001 --> 00:01:48,009
as if they are public by classes,

40
00:01:48,009 --> 00:01:52,002
which inherit from the class
with the protected variables.

41
00:01:52,002 --> 00:01:54,004
We will add, and discuss,
the contents of the

42
00:01:54,004 --> 00:01:57,009
Playable Character.h
file in three sections.

43
00:01:57,009 --> 00:02:00,009
First, the protected
section, followed by private,

44
00:02:00,009 --> 00:02:02,000
then public.

45
00:02:02,000 --> 00:02:04,003
The first thing to notice
in the code we just wrote,

46
00:02:04,003 --> 00:02:06,007
is that all the variables are protected.

47
00:02:06,007 --> 00:02:09,001
This means that when we extend the class,

48
00:02:09,001 --> 00:02:11,008
all the variables we just
wrote, will be accessible

49
00:02:11,008 --> 00:02:14,000
to those classes that extended.

50
00:02:14,000 --> 00:02:17,005
We will extend this class
with Thomas and Bob Classes.

51
00:02:17,005 --> 00:02:20,004
Apart from the protected
access specification,

52
00:02:20,004 --> 00:02:23,004
there's nothing new, or
complicated, about this code.

53
00:02:23,004 --> 00:02:26,003
It is worth paying attention
to some of the details however.

54
00:02:26,003 --> 00:02:29,004
Then, it will be easy to
understand how the class works,

55
00:02:29,004 --> 00:02:30,008
as we progress.

56
00:02:30,008 --> 00:02:33,001
So, let's run through
those protected variables,

57
00:02:33,001 --> 00:02:35,000
one at a time.

58
00:02:35,000 --> 00:02:37,004
First of all, we have
our, somewhat predictable,

59
00:02:37,004 --> 00:02:40,001
Sprite, m_Sprite.

60
00:02:40,001 --> 00:02:42,003
That is, we are declaring
an object of Sprite,

61
00:02:42,003 --> 00:02:44,008
called m_Sprite.

62
00:02:44,008 --> 00:02:48,003
We have a float called m_JumpDuration,

63
00:02:48,003 --> 00:02:50,007
which will hold the value
representing the time that the

64
00:02:50,007 --> 00:02:52,007
character is able to jump for.

65
00:02:52,007 --> 00:02:55,001
The greater the value, the
higher the character will be

66
00:02:55,001 --> 00:02:56,007
able to jump.

67
00:02:56,007 --> 00:03:00,008
Next, we have boolean, m_ IsJumping,

68
00:03:00,008 --> 00:03:02,008
which is true when the
character is jumping,

69
00:03:02,008 --> 00:03:04,005
and falls otherwise.

70
00:03:04,005 --> 00:03:06,008
This will be useful for
making sure that the character

71
00:03:06,008 --> 00:03:09,001
can't jump while in mid-air.

72
00:03:09,001 --> 00:03:12,008
The m_ IsFalling variable,
has a similar use,

73
00:03:12,008 --> 00:03:15,004
to m_IsJumping.

74
00:03:15,004 --> 00:03:18,003
It will be useful to know
when a character is falling.

75
00:03:18,003 --> 00:03:21,000
It's also a bolean variable.

76
00:03:21,000 --> 00:03:23,007
Next we have two boolean's,
which would be true,

77
00:03:23,007 --> 00:03:26,000
if the character's left
or right keyboard buttons,

78
00:03:26,000 --> 00:03:28,000
are currently being pressed.

79
00:03:28,000 --> 00:03:30,002
These are relative,
depending upon the character.

80
00:03:30,002 --> 00:03:35,000
Keys, A and D for Thomas, left
and right arrow keys for Bob.

81
00:03:35,000 --> 00:03:37,006
How we respond to these
booleans, will be seen in the

82
00:03:37,006 --> 00:03:39,009
Thomas and Bob Classes.

83
00:03:39,009 --> 00:03:43,008
The m_TimeThisJump float
variable, is updated,

84
00:03:43,008 --> 00:03:48,000
each and every frame,
the m_IsJumping is true.

85
00:03:48,000 --> 00:03:52,002
We can then know when m_Jump
duration has been reached.

86
00:03:52,002 --> 00:03:57,003
The final protected variable,
is the boolean m_JustJumped,

87
00:03:57,003 --> 00:03:59,006
this will be true if a jump was initiated,

88
00:03:59,006 --> 00:04:01,001
in the current frame.

89
00:04:01,001 --> 00:04:02,004
It will be useful for knowing

90
00:04:02,004 --> 00:04:04,005
when to play a jump sound effect.

91
00:04:04,005 --> 00:04:09,009
As of now, we have set
m_JustJumped, to false.

92
00:04:09,009 --> 00:04:12,009
Next, at this highlighted
code, where we are adding

93
00:04:12,009 --> 00:04:17,000
private variables to the
Playable Character.h file.

94
00:04:17,000 --> 00:04:19,006
We have some interesting
private variables here.

95
00:04:19,006 --> 00:04:22,002
Remember that these variables
will only be directly

96
00:04:22,002 --> 00:04:25,007
accessible to the code, in
the Playable Character Class.

97
00:04:25,007 --> 00:04:28,000
The Thomas and Bob classes,
will not be able to

98
00:04:28,000 --> 00:04:29,008
access them directly.

99
00:04:29,008 --> 00:04:33,005
The m_Gravity variable, will
hold the number of pixels

100
00:04:33,005 --> 00:04:36,002
per second that the character will fall.

101
00:04:36,002 --> 00:04:39,008
The m_Speed variable, will
hold the number of pixels

102
00:04:39,008 --> 00:04:43,006
per second that the character
can move left, or right.

103
00:04:43,006 --> 00:04:46,008
The Vector2f m_Position variable,

104
00:04:46,008 --> 00:04:49,006
is the position in the
world, not the screen,

105
00:04:49,006 --> 00:04:52,003
where the center of the character is.

106
00:04:52,003 --> 00:04:56,006
The next four float rect objects,
are important to discuss.

107
00:04:56,006 --> 00:04:59,005
When we did collision detection
in the Zombie Arena game,

108
00:04:59,005 --> 00:05:00,007
we simply checked to see if,

109
00:05:00,007 --> 00:05:03,004
two float rect objects intersected.

110
00:05:03,004 --> 00:05:07,000
Each float rect object,
represented an entire character,

111
00:05:07,000 --> 00:05:08,007
a pick up, or a bullet.

112
00:05:08,007 --> 00:05:10,009
For the non-rectangular shaped objects,

113
00:05:10,009 --> 00:05:12,001
zombies and the player,

114
00:05:12,001 --> 00:05:14,005
this was a little bit inaccurate.

115
00:05:14,005 --> 00:05:17,004
In this game, we will
need to be more precise.

116
00:05:17,004 --> 00:05:25,003
The m_Feet, m_Head, m_Right
and m_Left float rect objects,

117
00:05:25,003 --> 00:05:27,003
will hold the co-ordinates
of the different parts

118
00:05:27,003 --> 00:05:28,009
of a character's body.

119
00:05:28,009 --> 00:05:30,006
These co-ordinates will be updated,

120
00:05:30,006 --> 00:05:32,006
in each and every frame.

121
00:05:32,006 --> 00:05:34,009
Through these co-ordinates, we
will be able to tell exactly

122
00:05:34,009 --> 00:05:37,007
when a character lands on
a platform, bumps his head

123
00:05:37,007 --> 00:05:41,008
during a jump or, rubs shoulders
with a tile to his side.

124
00:05:41,008 --> 00:05:44,000
Lastly, we have texture, that is,

125
00:05:44,000 --> 00:05:46,004
we declare an object of type texture,

126
00:05:46,004 --> 00:05:49,001
called m_Texture.

127
00:05:49,001 --> 00:05:52,001
Texture is private, as
it is not used directly,

128
00:05:52,001 --> 00:05:54,000
by the Thomas or Bob Classes,

129
00:05:54,000 --> 00:05:56,008
but as we saw, Sprite is protected,

130
00:05:56,008 --> 00:05:59,004
because it is used directly.

131
00:05:59,004 --> 00:06:01,006
Now, add all the public functions to the

132
00:06:01,006 --> 00:06:04,001
Playable Character.h file,

133
00:06:04,001 --> 00:06:08,000
this is the entire
highlighted code to be added.

134
00:06:08,000 --> 00:06:10,003
Let's talk about each of
the function declarations

135
00:06:10,003 --> 00:06:11,006
that we just added.

136
00:06:11,006 --> 00:06:15,000
This will make coding their
definitions, easier to follow.

137
00:06:15,000 --> 00:06:18,005
First, the Spawn function
receives a vector2f called,

138
00:06:18,005 --> 00:06:21,006
Start Position, and a
float called Gravity.

139
00:06:21,006 --> 00:06:24,002
As the name suggests,
Start Position will be the

140
00:06:24,002 --> 00:06:27,001
co-ordinates in the level at
which the character will start,

141
00:06:27,001 --> 00:06:29,006
and Gravity will be the
number of pixels per second,

142
00:06:29,006 --> 00:06:32,001
at which the character will fall.

143
00:06:32,001 --> 00:06:35,001
The bool virtual handle input = 0,

144
00:06:35,001 --> 00:06:38,006
is, of course, our pure virtual function.

145
00:06:38,006 --> 00:06:41,000
As Playable Character has this function,

146
00:06:41,000 --> 00:06:44,001
any class that extends it,
if we want to instantiate it,

147
00:06:44,001 --> 00:06:46,009
must provide a definition
for this function.

148
00:06:46,009 --> 00:06:49,007
Therefore, when we write all
the function definitions for

149
00:06:49,007 --> 00:06:51,005
Playable Character in the minute,

150
00:06:51,005 --> 00:06:55,000
we will not provide a
definition for handle input.

151
00:06:55,000 --> 00:06:56,008
There will, of course,
need to be definitions,

152
00:06:56,008 --> 00:06:59,008
in both the Thomas and Bob Classes.

153
00:06:59,008 --> 00:07:02,008
The Get Position function,
returns a float rect,

154
00:07:02,008 --> 00:07:05,007
that represents the position
of the whole character.

155
00:07:05,007 --> 00:07:08,002
The Get Feet function,
as well as Get Head,

156
00:07:08,002 --> 00:07:11,007
Get Right and Get Left,
each return a float rect,

157
00:07:11,007 --> 00:07:13,008
that represents the
location of a specific part

158
00:07:13,008 --> 00:07:15,004
of the character's body.

159
00:07:15,004 --> 00:07:19,000
This is just what we need, for
detailed collision detection.

160
00:07:19,000 --> 00:07:22,002
The Get Sprite function,
as usual, returns a copy

161
00:07:22,002 --> 00:07:25,003
of m_Sprite, to the calling code.

162
00:07:25,003 --> 00:07:28,005
The StopFalling, StopRight and StopLeft,

163
00:07:28,005 --> 00:07:30,003
receive a single float value.

164
00:07:30,003 --> 00:07:32,003
Which the function will
use, to reposition the

165
00:07:32,003 --> 00:07:34,005
character, and stop it walking or jumping,

166
00:07:34,005 --> 00:07:36,002
through a solid tile.

167
00:07:36,002 --> 00:07:38,007
The StopJump function,
will stop the character,

168
00:07:38,007 --> 00:07:41,005
from jumping through a solid tile.

169
00:07:41,005 --> 00:07:44,004
The GetCenter function,
returns a vector2f,

170
00:07:44,004 --> 00:07:46,009
to the calling code, to
let it know exactly where

171
00:07:46,009 --> 00:07:49,000
the center of the character is.

172
00:07:49,000 --> 00:07:52,006
This value is, of course,
held in m_Position.

173
00:07:52,006 --> 00:07:55,006
We will see later, that it
is used by the Engine Class,

174
00:07:55,006 --> 00:07:57,003
to center the appropriate view around

175
00:07:57,003 --> 00:07:59,009
the appropriate character.

176
00:07:59,009 --> 00:08:03,001
The update function, we
have seen many times before,

177
00:08:03,001 --> 00:08:05,006
and, as usual, it takes float parameter,

178
00:08:05,006 --> 00:08:07,000
which is the fraction of a second,

179
00:08:07,000 --> 00:08:09,002
that the current frame is taken.

180
00:08:09,002 --> 00:08:11,004
This update function,
will need to do more work,

181
00:08:11,004 --> 00:08:14,002
than previous update
functions, from other projects.

182
00:08:14,002 --> 00:08:16,004
However, it will need to handle jumping,

183
00:08:16,004 --> 00:08:18,005
as well as updating the
float rect objects that

184
00:08:18,005 --> 00:08:21,009
represent the head, feet, left and right.

185
00:08:21,009 --> 00:08:24,006
Now, we can write the definitions
for all the functions,

186
00:08:24,006 --> 00:08:27,005
except, of course, handle input.

187
00:08:27,005 --> 00:08:31,007
Now, let's move on to coding
Playable Character.cpp.

188
00:08:31,007 --> 00:08:34,004
Just like we always do,
right click Source Files,

189
00:08:34,004 --> 00:08:37,008
in the Solution Explorer,
and select Add New Item.

190
00:08:37,008 --> 00:08:42,000
Click, c++ File.cpp, and
then in the name field,

191
00:08:42,000 --> 00:08:46,000
type Playable Character, and click Add.

192
00:08:46,000 --> 00:08:48,006
We are now ready to code the .cpp file,

193
00:08:48,006 --> 00:08:51,007
for the Playable Character Class.

194
00:08:51,007 --> 00:08:53,008
We will break up the code, and discussion,

195
00:08:53,008 --> 00:08:55,007
into a number of chunks.

196
00:08:55,007 --> 00:08:58,006
First, add the Include
Directives, and the definition

197
00:08:58,006 --> 00:09:00,007
of the Spawn function.

198
00:09:00,007 --> 00:09:04,001
The Spawn function,
initializes m_Position,

199
00:09:04,001 --> 00:09:05,009
with the past in position.

200
00:09:05,009 --> 00:09:10,005
That is, m_Positionx = StartPositionx and,

201
00:09:10,005 --> 00:09:14,005
m_Positiony = StartPositiony.

202
00:09:14,005 --> 00:09:19,001
It also initializes m_Gravity,
and this final line of code,

203
00:09:19,001 --> 00:09:23,006
moves m_Sprite, to it's starting position.

204
00:09:23,006 --> 00:09:26,009
Next, add the definition
for the Update function.

205
00:09:26,009 --> 00:09:29,004
Add this entire highlighted
code immediately after

206
00:09:29,004 --> 00:09:31,006
the preceding code.

207
00:09:31,006 --> 00:09:36,000
Here, first we check whether
m_RightPressed is true.

208
00:09:36,000 --> 00:09:40,003
If it is, m_Position is
changed, using this formula,

209
00:09:40,003 --> 00:09:43,006
m_Speed into elapse time.

210
00:09:43,006 --> 00:09:47,008
The same is done for
m_LeftPressed, in case it's true,

211
00:09:47,008 --> 00:09:52,000
it changes m_Position using this formula.

212
00:09:52,000 --> 00:09:54,001
Then, we see whether or not the character,

213
00:09:54,001 --> 00:09:56,003
is currently executing a jump.

214
00:09:56,003 --> 00:09:58,005
If this if statement is true,

215
00:09:58,005 --> 00:10:03,006
the code first updates
m_TimeThisJump, with elapse time.

216
00:10:03,006 --> 00:10:08,004
Then, it checks if m_TimeThisJump
is still less than,

217
00:10:08,004 --> 00:10:11,005
m_JumpDuration, if it is,

218
00:10:11,005 --> 00:10:15,000
change the y co-ordinate of m_Position by

219
00:10:15,000 --> 00:10:18,005
twice Gravity multiplied
by the elapse time.

220
00:10:18,005 --> 00:10:22,008
In the else clause, it executes
when m_TimeThisJump is,

221
00:10:22,008 --> 00:10:25,009
not lower than m_JumpDuration,

222
00:10:25,009 --> 00:10:29,001
then m_Falling is set to true.

223
00:10:29,001 --> 00:10:32,007
Also, m_Jumping is set to false.

224
00:10:32,007 --> 00:10:35,002
This prevents the code we
have just been discussing,

225
00:10:35,002 --> 00:10:36,004
from executing.

226
00:10:36,004 --> 00:10:40,007
As if m_IsJumping, is now false.

227
00:10:40,007 --> 00:10:47,001
Next, if m_IsFalling block moves
m_Position down each frame,

228
00:10:47,001 --> 00:10:50,009
it is moved, using the
current value of m_Gravity

229
00:10:50,009 --> 00:10:52,005
and the elapse time.

230
00:10:52,005 --> 00:10:55,009
That is, using the current
value of m_Gravity,

231
00:10:55,009 --> 00:10:57,009
and the elapse time.

232
00:10:57,009 --> 00:11:00,008
This code, which is almost
all of the remaining code,

233
00:11:00,008 --> 00:11:03,000
updates the body parts of the character,

234
00:11:03,000 --> 00:11:06,001
relative to the current position
of the Sprite, as a whole.

235
00:11:06,001 --> 00:11:08,000
Take a look at this diagram,

236
00:11:08,000 --> 00:11:10,000
to see how the code
calculates the position,

237
00:11:10,000 --> 00:11:12,009
of the virtual head, feet,
left and right sides,

238
00:11:12,009 --> 00:11:14,005
of the character.

239
00:11:14,005 --> 00:11:17,008
This final line of code,
uses the set position of

240
00:11:17,008 --> 00:11:20,000
function, to move the
Sprite to it's corrected

241
00:11:20,000 --> 00:11:24,002
location after all the possibilities
of the update function.

242
00:11:24,002 --> 00:11:27,009
Now, add this code, right
after the previous one.

243
00:11:27,009 --> 00:11:30,009
Here we are adding the
definition for the Get Position,

244
00:11:30,009 --> 00:11:35,001
GetCenter, GetFeet, GetHead,
GetLeft, GetRight and

245
00:11:35,001 --> 00:11:37,008
GetSprite functions.

246
00:11:37,008 --> 00:11:40,007
The GetPosition function,
returns a float rect,

247
00:11:40,007 --> 00:11:43,006
that wraps the entire Sprite
and Get Center returns

248
00:11:43,006 --> 00:11:47,005
a vector2f, which contains
the center of the Sprite.

249
00:11:47,005 --> 00:11:50,005
Notice, that we divide the
height and width of the Sprite,

250
00:11:50,005 --> 00:11:54,005
by two, in order to dynamically
arrive at this result.

251
00:11:54,005 --> 00:11:56,005
This is because Thomas and Bob,

252
00:11:56,005 --> 00:11:58,003
will be at different heights.

253
00:11:58,003 --> 00:12:02,000
The GetFeet, GetHead, GetLeft
and GetRight functions,

254
00:12:02,000 --> 00:12:04,005
return the float rect
objects that represent the

255
00:12:04,005 --> 00:12:07,007
body parts of the character,
that we update each frame,

256
00:12:07,007 --> 00:12:09,007
in the update function.

257
00:12:09,007 --> 00:12:11,008
The Get Sprite function, as usual,

258
00:12:11,008 --> 00:12:15,002
returns a copy of m_Sprite.

259
00:12:15,002 --> 00:12:17,008
Finally, for the Playable Character Class,

260
00:12:17,008 --> 00:12:20,007
add the definitions for
the, StopFalling, StopRight,

261
00:12:20,007 --> 00:12:23,005
StopLeft and StopJump functions.

262
00:12:23,005 --> 00:12:27,004
Note that to do so, immediately
after the previous code.

263
00:12:27,004 --> 00:12:30,003
Each of these function receive
a value, as a parameter,

264
00:12:30,003 --> 00:12:32,008
that is used to reposition either the top,

265
00:12:32,008 --> 00:12:35,008
bottom, left or right of the Sprite.

266
00:12:35,008 --> 00:12:39,000
Exactly what these values are,
and how they are obtained,

267
00:12:39,000 --> 00:12:40,008
will be seen later.

268
00:12:40,008 --> 00:12:44,008
Each of the previous functions
also repositions the Sprite.

269
00:12:44,008 --> 00:12:47,009
The final function is
the StopJump function,

270
00:12:47,009 --> 00:12:50,006
that will also be used
in collision detection.

271
00:12:50,006 --> 00:12:54,006
It sets the necessary
values for m_IsJumping and,

272
00:12:54,006 --> 00:12:57,007
m_IsFalling, to end a jump.

273
00:12:57,007 --> 00:13:01,001
Here we have set m_IsJumping to false,

274
00:13:01,001 --> 00:13:04,000
and m_IsJumping to true.

275
00:13:04,000 --> 00:13:05,005
In this video, we have learned,

276
00:13:05,005 --> 00:13:08,001
Building the Playable Character Class.

277
00:13:08,001 --> 00:13:09,001
Cool.

278
00:13:09,001 --> 00:13:11,001
In the next video, we
will see building the

279
00:13:11,001 --> 00:13:13,001
Thomas and Bob Classes.

