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.
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() * cVector::XAXIS); if (pcontroller->keyoncontrol(VK_DOWN)) pcritter->setVelocity(pcritter->maxspeed() * cVector::YAXIS); if (pcontroller->keyoncontrol(VK_UP)) pcritter->setVelocity(- pcritter->maxspeed() * cVector::YAXIS); if (!pcontroller->keyoncontrol(VK_LEFT) && !pcontroller->keyoncontrol(VK_RIGHT) && !pcontroller->keyoncontrol(VK_DOWN) && !pcontroller->keyoncontrol(VK_UP) ) pcritter->setVelocity(cVector::ZEROVECTOR); // 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)) pcritterv->zoom(cCritterViewer::DEFAULTZOOMFACTOR); if (pcontroller->keyon(VK_DELETE)) pcritterv->zoom(1.0/cCritterViewer::DEFAULTZOOMFACTOR); } 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. |