12.4 Viewer listeners

Each CPopView has a cCritterViewer *_pviewpointcritter member that is used to set the projection matrix and the view matrix inside the CPopView::OnDraw call. We discuss the details of this process in Chapter 24: Two- and Three-dimensional Graphics. But the basic notion is simple: a view shows the game world as seen from the viewpoint of its _pviewpointcritter.

The user changes the appearance of the view by moving or rotating the _pviewpointcritter. It's also possible to change the magnification scale, or field of view angle, by making a pviewpointcritter->zoom(zoomfactor) call.

In order to let the user change the viewpoint, the CPopView code can attach a listener to the viewer with a call like _pviewpointcritter->setListener(new cListenerViewerOrtho()). The cListenerViewerOrtho is one of the three specialized cListener child classes that the Pop Framework provides for use with the viewers. Let's say a few words about the three kinds of viewer listeners.

  • cListenerViewerOrtho is always used as the _pviewpointcritter listener for two-dimensional worlds. This listener reacts to Ctrl+Arrow key combinations to move the _pviewpointcritter back and forth parallel to the XY plane, and it causes the Ins and Del keys to generate zoom calls.

  • Either cListenerViewerFly or cListenerViewerRide are always used as the _pviewpointcritter listener for three-dimensional worlds. cListenerViewerFly reacts to the Ctrl+Arrow key combinations to move the _pviewpointcritter along its intrinsic axes, that is along its tangent, normal, and binormal directions. The Ctrl+Shift+Arrow key combinations rotate the _pviewpointcritter around its intrinsic axes, and the Ins and Del keys zoom the viewpoint.

  • cListenerViewerRide is used in three-dimensional worlds to let the viewer 'ride' upon the game's pplayer(). That is, this listener maintains a fixed cVector _offset, keeps the _pviewpointcritter always at this offset from the player's position, and adjusts the _pviewpointcritter attitude to change along with the player's attitude. (Rather than exactly matching the player attitude to look parallel to the player, we have the rider tilt a bit to look at a point slightly ahead of the player.) The Ctrl+Arrow keys can be used to change the viewer's fixed offset from the player.

Here as an example is the cListenerViewerOrtho::listen code.

void cListenerViewerOrtho::listen(Real dt, cCritter *pcritter) 
    cController *pcontroller = pcritter->pgame()->pcontroller(); 
// Use the Control + (Arrow keys, Insert or Delete) to translate. 
    if (pcontroller->keyoncontrol(VK_LEFT)) 
        pcritter->setVelocity(pcritter->maxspeed() * cVector::XAXIS); 
    if (pcontroller->keyoncontrol(VK_RIGHT)) 
        pcritter->setVelocity(- pcritter->maxspeed() * 
    if (pcontroller->keyoncontrol(VK_DOWN)) 
        pcritter->setVelocity(pcritter->maxspeed() * cVector::YAXIS); 
    if (pcontroller->keyoncontrol(VK_UP)) 
        pcritter->setVelocity(- pcritter->maxspeed() * 
    if (!pcontroller->keyoncontrol(VK_LEFT) && 
        !pcontroller->keyoncontrol(VK_RIGHT) && 
        !pcontroller->keyoncontrol(VK_DOWN) && 
        !pcontroller->keyoncontrol(VK_UP) ) 
// Use the Insert, Delete keys to zoom. 
    cCritterViewer *pcritterv = (cCritterViewer*)(pcritter); /* Need 
        the cast to use zoom 
    ASSERT(pcritterv); //To make sure the cast didn't fail. */ 
    if (pcontroller->keyon(VK_INSERT)) 
    if (pcontroller->keyon(VK_DELETE)) 

Note that the Ctrl+Left combination moves the _pviewpointcritter to the right, which gives an effect of the visible world moving to the left. Users tend not to think in terms of there being a separate _pviewpointcritter (and why should they?), so it makes for a better interface to move the visible world in the direction of the arrows.

In most of our games both the player and the _pviewpointcritter will have a listener, and at every full update of the game, each of them gets a chance to 'listen' to the key information in the game's cController object.

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