|
|
12.4 Viewer listenersEach 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. |
|
|