Picking Up a Key


It's common in games for characters to pick up powerups, keys for doors, and so on. It's not hard to add that ability to Invasion of the Slugwroths. I'll present an example program, Program 17.2 on the CD, that enables Captain Chloride to pick up a key card. If he has the red key, he can open the red door. If not, the door won't open.

Objects that Can be Picked Up

The first step is to add a class that represents the object to be picked up. The class, as you might expect, is called key. Listing 17.5 presents its class definition.

Note

This code is from the file Key.h in the folder Source\Chapter17\Prog_17_02 on the CD.


Listing 17.5. The definition of the key class

 1   class key : public world_object 2   { 3   public: 4      key(); 5 6      std::string Type(); 7 8      bool Render( 9         invasion *theGame); 10 11   private: 12       vectorf velocity; 13 14   public: 15       sprite mySprite; 16   }; 

The key class has very little code because a key doesn't do much. It just lies there until Captain Chloride picks it up. Once he does, it's no longer visible on the screen. This isn't handled directly by the key class. Instead, the world_object class contains a private data member named visible. When visible is set to false, the object becomes essentially invisible. Because the key class inherits from world_object, it too can become invisible when needed.

The key class contains a data member of type sprite. The class uses this member to display the key's image on the screen.

Warning

The mySprite member of the key class is another example of me making a data member public rather than private for simplicity. In a professional program, I would never do this because it can lead to accidental data corruption.


The member functions for the key class are equally simple. The only one I'll present here is the Render() function. If you want to see the others, please look at the source code on the CD. The key class's Render() function appears in Listing 17.6.

Listing 17.6. The Render() function from the key class

 1   bool key::Render(invasion *theGame) 2   { 3      bool renderOK = true; 4      vector screenPos; 5      theGame>WorldToScreen(worldPos, screenPos); 6      mySprite.X(screenPos.X()); 7      mySprite.Y(screenPos.Y()); 8      renderOK = mySprite.Render(); 9 10     return (renderOK); 11   } 

Listing 17.6 shows that the Render() function sets the position of the key in the level and uses the sprite::Render() function to draw the key to the screen.

To get the key into the level, you create XML tags for it in the level file. You also need to add some code to the chloride_level class to parse the XML for the key, dynamically allocate a key object, and initialize it with the information from the XML tags. This is the same process you saw in chapter 16. Whether you're adding doors, keys, monsters, or whatever, you follow this same process. If you do, the game adds the key to the linked list of objects in the level. The game draws everything in the linked list every frame.

Note

You can see the XML tags for the key in the Invasion.xml file in the folder Source\Chapter17\Prog_17_02 on the CD. To see the code that parses the key's XML tags, please see the ObjectFactory() function in the file ChlorideLevel.cpp (which is in the same folder).


Making Captain Chloride Pick Things Up

Getting Captain Chloride to pick up a key requires only minor modifications to the chloride class. You just need to add a data member that is true when he has the key and false if not. If you want to play a sound whenever the Captain picks something up, which is a good idea, simply add a member of type sound to the chloride class and load the "pickup" sound into it. I added both of these members to the chloride class in Program 17.2 on the CD. To view them, please see the Chloride.h file in the folder Source\Chapter17\Prog_17_02.

Recall that the chloride class has a member function named Hit(). Whenever the Captain encounters an object with a bounding rectangle, the game calls the chloride::Hit() function. Therefore, that's where the code goes that controls what happens when Captain Chloride encounters a key. Listing 17.7 provides the code for the chloride class's Hit() function.

Listing 17.7. Enabling Captain Chloride to pick up a key

 1   void chloride::Hit(world_object &stationary) 2   { 3       if (stationary.Type() == "door") 4       { 5           door *theDoor = (door*)&stationary; 6 7           if (haveKey) 8           { 9              theDoor>Open( this); 10          } 11 12          worldPos = velocity; 13 14          bonkSound.Play(); 15      } 16      else if (stationary.Type() == "key") 17      { 18            key *theKey = (key*)&stationary; 19            theKey>Visible(false); 20            theKey>Collidable(false); 21            pickupSound.Play(); 22            haveKey = true; 23      } 24   } 

The code on line 19 of Listing 17.7 marks the key as invisible when the Captain collides with it. It also turns off the key's collision checking on line 20. The Hit() function plays a blip sound to notify the player that the Captain picked up the key. It also sets the chloride class's haveKey member to true.

As the Captain continues to walk around his world, he eventially collides with the door. When he does, the game calls the Hit() function again. This time, it executes the code on lines 514. If Captain Chloride has the key, the Hit() function calls the door's Open() function. In the Open() function, the door opens by sliding upward. As it does, you'll hear a nice door opening sound. When the Captain moves away from the door, it closes. The next section explains how all of that happens.



Creating Games in C++(c) A Step-by-Step Guide
Creating Games in C++: A Step-by-Step Guide
ISBN: 0735714347
EAN: 2147483647
Year: N/A
Pages: 148

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net