Now we get to use inheritance for real. We will build a class for Thomas and a class for Bob. They will both inherit from the PlayableCharacter
class we just coded. They will then have all the functionality of the PlayableCharacter
class, including direct access to its protected
variables. We will also add the definition for the pure virtual function handleInput
. You will notice that the handleInput
functions for Thomas
and Bob
will be different.
Right-click Header Files in the Solution Explorer and select Add | New Item.... In the Add New Item window, highlight (by left-clicking) Header File (.h
) and then in the Name field, type Thomas.h
. Finally, click the Add button. We are now ready to code the header file for the Thomas
class.
Now add this code to the Thomas.h
class:
#pragma once #include "PlayableCharacter.h" class Thomas : public PlayableCharacter { public: // A constructor specific to Thomas Thomas::Thomas(); // The overridden input handler for Thomas bool virtual handleInput(); };
The previous code is very short and sweet. We can see that we have a constructor and that we are going to implement the pure virtual handleInput
function, so let's do that now.
Right-click Source Files in the Solution Explorer and select Add | New Item.... In the Add New Item window, highlight (by left-clicking) C++ File (.cpp
) and then in the Name field, type Thomas.cpp
. Finally, click the Add button. We are now ready to code the .cpp
file for the Thomas
class.
Add the Thomas
constructor to the Thomas.cpp
file, as shown in the following snippet:
#include "stdafx.h" #include "Thomas.h" #include "TextureHolder.h" Thomas::Thomas() { // Associate a texture with the sprite m_Sprite = Sprite(TextureHolder::GetTexture( "graphics/thomas.png")); m_JumpDuration = .45; }
All we need to do is load the thomas.png
graphic and set the duration of a jump (m_JumpDuration
) to .45
(nearly half a second).
Add the definition of the handleInput
function, as shown in the following snippet:
// A virtual function bool Thomas::handleInput() { m_JustJumped = false; if (Keyboard::isKeyPressed(Keyboard::W)) { // Start a jump if not already jumping // but only if standing on a block (not falling) if (!m_IsJumping && !m_IsFalling) { m_IsJumping = true; m_TimeThisJump = 0; m_JustJumped = true; } } else { m_IsJumping = false; m_IsFalling = true; } if (Keyboard::isKeyPressed(Keyboard::A)) { m_LeftPressed = true; } else { m_LeftPressed = false; } if (Keyboard::isKeyPressed(Keyboard::D)) { m_RightPressed = true; } else { m_RightPressed = false; } return m_JustJumped; }
This code should look quite familiar. We are using the SFML isKeyPressed
function to see whether any of the W, A, or D keys are pressed.
When W is pressed, the player is attempting to jump. The code then uses the if(!m_IsJumping && !m_IsFalling)
code, which checks that the character is not already jumping and that it is not falling either. When these tests are both true, m_IsJumping
is set to true
, m_TimeThisJump
is set to zero, and m_JustJumped
is set to true.
When the previous two tests don't evaluate to true
, the else
clause is executed and m_Jumping
is set to false
and m_IsFalling
is set to true.
The handling of the A and D
keys being pressed is as simple as setting m_LeftPressed
and/or m_RightPressed
to true
or false
. The update
function will now be able to handle moving the character.
The last line of code in the function returns the value of m_JustJumped
. This will let the calling code know if it needs to play a jumping sound effect.
We will now code the Bob
class, although this is nearly identical to the Thomas
class, except it has different jumping abilities, a different Texture
, and uses different keys on the keyboard.
The Bob
class is identical in structure to the Thomas
class. It inherits from PlayableCharacter
, it has a constructor, and it provides the definition of the handleInput
function. The difference compared to Thomas
is that we initialize some of Bob's member variables differently and we handle input (in the handleInput
function) differently as well. Let's code the class and see the details.
Right-click Header Files in the Solution Explorer and select Add | New Item.... In the Add New Item window, highlight (by left-clicking) Header File (
.h
) and then in the Name field, type Bob.h
. Finally, click the Add button. We are now ready to code the header file for the Bob
class.
Add the following code to the Bob.h
file:
#pragma once #include "PlayableCharacter.h" class Bob : public PlayableCharacter { public: // A constructor specific to Bob Bob::Bob(); // The overriden input handler for Bob bool virtual handleInput(); };
The previous code is identical to the Thomas.h
file apart from the class name, and therefore, the constructor name.
Right-click Source Files in the Solution Explorer and select Add | New Item.... In the Add New Item window, highlight (by left-clicking) C++ File (
.cpp
) and then in the Name field, type Thomas.cpp
. Finally, click the Add button. We are now ready to code the .cpp
file for the Bob
class.
Add the code for the Bob
constructor to the Bob.cpp
file. Notice that the texture is different (bob.png
) and that m_JumpDuration
is initialized to a significantly smaller value. Bob is now his own, unique self:
#include "stdafx.h" #include "Bob.h" #include "TextureHolder.h" Bob::Bob() { // Associate a texture with the sprite m_Sprite = Sprite(TextureHolder::GetTexture( "graphics/bob.png")); m_JumpDuration = .25; }
Add the handleInput
code immediately after the Bob
constructor:
bool Bob::handleInput() { m_JustJumped = false; if (Keyboard::isKeyPressed(Keyboard::Up)) { // Start a jump if not already jumping // but only if standing on a block (not falling) if (!m_IsJumping && !m_IsFalling) { m_IsJumping = true; m_TimeThisJump = 0; m_JustJumped = true; } } else { m_IsJumping = false; m_IsFalling = true; } if (Keyboard::isKeyPressed(Keyboard::Left)) { m_LeftPressed = true; } else { m_LeftPressed = false; } if (Keyboard::isKeyPressed(Keyboard::Right)) { m_RightPressed = true;; } else { m_RightPressed = false; } return m_JustJumped; }
Notice that the code is nearly identical to the code in the handleInput
function of the Thomas
class. The only difference is that we respond to different keys (Left arrow key, Right arrow key, and Up arrow key for jump.)
Now we have a PlayableCharacter
class that has been extended by Bob
and Thomas
, we can add a Bob
and a Thomas
instance to the game.
18.117.187.113