12.3 Shooting with the listeners

As well as moving our critters around, we also want to be able to make them shoot bullets or, if you will, eject objects. We will allow two shooting input methods: pressing the spacebar or clicking the left mouse button while the cursor is in a view that uses the _hCursorPlay cursor. You select this cursor by clicking on the crosshair button in the toolbar or by selecting View | Shoot Cursor.

The framework checks on the cursor type in the CPopView::OnLButtonDown. This method only stores a left click in the game cController object in the case where the cursor type is indeed the _hCursorPlay.

We derive any critter that shoots from the critter child class cCritterArmedPlayer. We'll discuss cCritterArmedPlayer in some detail in the next chapter; for now it suffices to know that this class has a BOOL _bshooting member, and when bshooting is TRUE the cCritterArmedPlayer::update method can shoot a bullet.

Rather than putting shooting code into each of our listeners, it's more efficient to put it into the feellistener method of the cCritterArmedPlayer itself. Leaving out a few complications, the method looks basically like this.

void cCritterArmedPlayer::feellistener(Real dt) 
    _bshooting = (pgame()->keystate(VK_SPACE) == cController::KEYON); 
    if (pgame()->keystate(VK_LBUTTON) == cController::KEYON) 
        /* shoot with left mouse click 
        The controller will only have turned VK_LBUTTON on if you 
        left clicked the Shoot Cursor; left clicks with other 
        cursors will be ignored by controller. */ 
        _bshooting = TRUE; 

Using the shooting cursor makes a nice interface for many games. As it turns out, users have trouble using complicated listeners to move the player. Much of the challenge of Asteroids (or our Spacewar) is that the cListenerSpaceship is so hard to use. The cListenerCar is in fact only practical for things like car races around an onscreen track. Ordinarily, users will prefer either the cListenerScooter or even the lowly cListenerArrow.

One of the drawbacks of a cListenerArrow for a shooting game is that the critter seemingly can only shoot in the cardinal directions: East, North, West, and South. But if you use a Shoot mode cursor, that is, the _hCursorPlay, with the cListenerArrow, then you can shoot in any direction by left clicking. An interesting side-effect (that you could of course code out if you don't like it) is that when you press the Up Arrow and hold down the left mouse button, a critter with the cListenerArrow will continuously move towards the cursor location.

    Part I: Software Engineering and Computer Games
    Part II: Software Engineering and Computer Games Reference