A race against the clock to unpack jewels from a box. We show a mixture of white bubbles and colored bubbles. Think of the colored bubbles as valuable jewels, with the white bubbles being disposable Styrofoam packing peanuts. The image of the Pop game is of someone unpacking a box filled with precious baubles packed in plastic peanuts. You want to pop the peanuts and keep the baubles. Another way of thinking of it, perhaps, is of an archaeologist digging up valuable relics. The idea is to get rid of all the dirt and not harm the treasure.
Below is a screen capture of how the game looks.
We use the mouse control. The mouse uses one of two kinds of cursor tool, a popping tool and a dragging tool. Use the mouse wheel or the toolbar to select which cursor tool.
There are two kinds of disks on the screen. Some are like bubbles that the user has to pop, and some are like jewels that the user wants to save. The screen is divided into two parts; at the start all the disks are on the left, and the user has to drag the jewels to the right.
PickNPop in a 2D Windows graphics display. For a 3D view, see the plate on page 482
Assign the score so that a perfect game gives you 1000 points. You get a positive score for popping a bubble or for dragging a jewel to the right-hand box. You get a negative penalty if you pop a jewel.
As usual, most of our design is inherited from the Pop Framework. The new design we do for PickNPop involves two things: add some new cCritter children, and add a new cGamePicknpop.
As this game doesn't have a visible player, we'll give the new game an offscreen player, which will be used as a place to accumulate the game score.
We'll also give the game two cGraphicRealBox2 objects, a _packingbox and a _targetbox, with the peanuts and jewels starting in the _packingbox, and the player's task to move the jewels into the _targetbox.
We'll make a new kind of critter for each of the game elements: the peanuts, the jewels, and the promoted or 'unpacked' jewels.
Each critter will have a characteristic appearance that we set by picking a special kind of sprite in the critter constructor. In terms of a class diagram, we'll do it as shown in Figure 17.1.
We override the constructors of these critters so as to give them the appropriate sprites. We'll also set their _value fields.
In terms of methods to override, we'll override the cCritter::die() method for all three of these child critters. In each case, we'll have this method make a sound and add a number based on the _value to the game player, that is to _pownerbiota->pgame()->pplayer().
One other method to override is the cCritterJewel::update. This method will be responsible for noticing if the critter has been moved into the targetbox. If so, the critter will have to replace itself with a cCritterGoodJewel.
Regarding the sprites, we'll have a cSpriteBubble sprite designed for drawing circles, with the cSpriteBubbleGrayscale and cSpriteBubblePie inheriting from it. The cSpriteBubble will in turn inherit from cPolygon, which is a child of cSprite to be discussed in the next chapter. Although a circle really isn't a polygon, it's convenient to derive cSpriteBubble from cPolygon, because the polygon class already has all the fields, mutators, and accessors for setting things like the colors and the edgewidths. We will view a circle as a 'one-gon' polygon characterized by a center and a single vertex, which lies on the circumference of the circle.