Game Development Reference
In-Depth Information
The
Evaluate
method is where the
Chest::Open
call is made. The method first checks to see if the
Chest
is closed; if it is, then the
Open
call is made and the
Item
pointer is passed to
Player::AddItem
.
The last task is to print a message informing the player which
Item
was obtained from the
Chest
.
The
Evaluate
method brings us nicely to our next example of STL containers in our game. The
Player
class requires storage for the
Item
objects that the user can obtain. You can see in Listing 19-11
that a
vector<Item*>
has been added to the
Player
class.
Listing 19-11. The
Player
Class's
Item vector
class Player
: public Entity
{
private:
using Items = std::vector<Item*>;
Items m_items;
void AddItem(const Item* item)
{
m_items.push_back(const_cast<Item*>(item));
}
bool HasWeapon()
{
bool hasWeapon = false;
for (const Item* item : m_items)
{
const Sword* sword = dynamic_cast<const Sword*>(item);
if (sword != nullptr)
{
hasWeapon = true;
break;
}
}
return hasWeapon;
}
};
Listing 19-11 only shows the new code that has been added to
Player
. We now have an alias for the
Item* vector
, the
vector
instance and two new methods,
AddItem
and
HasWeapon
.
AddItem
is simply used to push new items onto the
m_items
vector. The
HasWeapon
method is a little
more interesting. It uses a
dynamic_cast
to determine if the current
Item
pointer is actually a
Sword
class. A
dynamic_cast
will return
nullptr
if the type conversion is invalid; therefore, only objects that
are actually
Swords
will successfully return a valid
Sword
pointer. Once we have a valid
Sword
pointer
we know that the player has a weapon, so
hasWeapon
can be set to
true
and we can
break
out of our
loop. The loop in question is a range-based
for
loop that takes advantage of our STL class.
The
Player
class has a method to determine whether the player is armed or not because we are
going to add enemies to some of the
Room
objects. Listing 19-12 shows the
Enemy
class.