📄 chapter7.txt
字号:
char Name;
DWORD Id;
WORD Defend;
WORD Attack;
...
};
第四节 游戏内部循环
游戏内部循环包括刷新游戏单位、画游戏单位两部分。它的实现过程是这样的:检测状态,作出判断,绘出新图。看起来这并不是一个循环,对吗?是的,游戏内部循环并不是一个真正的循环,它实际上是由消息循环完成循环作用的。让我们从例程中看看这是如何实现的吧!
在消息循环中的第一个else if语句是这样的
else if (!bPaused && (bIsActive || !bFullscreen))
{
ProcessFox(lastInput);
lastInput=0;
}
if 后的表达式的含义是:当游戏没有被暂停时(bPause为FLASE)或以窗口模式显示(bFullscreen为FLASE)且窗口处于活动状态(bIsActive为TRUE)时执行
{
ProcessFox(lastInput);
lastInput=0;
}
语句段。而函数ProcessFox(lastInput)通过调用ProcessInput()和NewGameFrame( )达成刷新游戏单元和重画新图的功能。(这三个函数的原代码见例程foxbear.c和gameproc.c两文件)。
ProcessFox(lastInput):
/*
* ProcessFox
*/
BOOL ProcessFox(SHORT sInput)
{
if ((lpFrontBuffer && IDirectDrawSurface_IsLost(lpFrontBuffer) == DDERR_SURFACELOST) ||
(lpBackBuffer && IDirectDrawSurface_IsLost(lpBackBuffer) == DDERR_SURFACELOST))
{
if (!RestoreGame())
{
PauseGame();
return FALSE;
}
}
ProcessInput(sInput);
NewGameFrame();
return TRUE;
} /* ProcessFox */
static HFONT hFont;
DWORD dwFrameCount;
DWORD dwFrameTime;
DWORD dwFrames;
DWORD dwFramesLast;
SIZE sizeFPS;
SIZE sizeINFO;
int FrameRateX;
char szFPS[] = "FPS %02d";
char szINFO[] = "%dx%dx%d%s F6=mode F8=x2 ALT+ENTER=Window";
char szINFOW[] = "%dx%dx%d%s F6=mode F8=x2 ALT+ENTER=Fullscreen";
char szFrameRate[128];
char szInfo[128];
COLORREF InfoColor = RGB(0,152,245);
COLORREF FrameRateColor = RGB(255,255,0);
COLORREF BackColor = RGB(255,255,255);
/*
* initNumSurface
*/
void initNumSurface( void )
{
HDC hdc;
RECT rc;
int len;
dwFramesLast = 0;
len = wsprintf(szFrameRate, szFPS, 0, 0);
if( lpFrameRate && IDirectDrawSurface_GetDC(lpFrameRate, &hdc ) == DD_OK )
{
SelectObject(hdc, hFont);
SetTextColor(hdc, FrameRateColor);
SetBkColor(hdc, BackColor);
SetBkMode(hdc, OPAQUE);
SetRect(&rc, 0, 0, 10000, 10000);
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, szFrameRate, len, NULL);
GetTextExtentPoint(hdc, szFrameRate, 4, &sizeFPS);
FrameRateX = sizeFPS.cx;
GetTextExtentPoint(hdc, szFrameRate, len, &sizeFPS);
IDirectDrawSurface_ReleaseDC(lpFrameRate, hdc);
}
if (bFullscreen)
len = wsprintf(szInfo, szINFO,
GameSize.cx, GameSize.cy, GameBPP,bStretch ? " x2" : "");
else
len = wsprintf(szInfo, szINFOW,
GameSize.cx, GameSize.cy, GameBPP,bStretch ? " x2" : "");
if( lpInfo && IDirectDrawSurface_GetDC(lpInfo, &hdc ) == DD_OK )
{
SelectObject(hdc, hFont);
SetTextColor(hdc, InfoColor);
SetBkColor(hdc, BackColor);
SetBkMode(hdc, OPAQUE);
SetRect(&rc, 0, 0, 10000, 10000);
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, szInfo, len, NULL);
GetTextExtentPoint(hdc, szInfo, len, &sizeINFO);
IDirectDrawSurface_ReleaseDC(lpInfo, hdc);
}
} /* initNumSurface */
NewGameFrame( ):
/*
* NewGameFrame
*/
int NewGameFrame( void )
{
SetSpriteX( hFox, 0, P_AUTOMATIC );
SetSpriteY( hFox, 0, P_AUTOMATIC );
SetPlaneVelX( hBackground, GetSpriteVelX(hFox), P_ABSOLUTE );
SetPlaneVelX( hMidground, GetSpriteVelX(hFox), P_ABSOLUTE );
SetPlaneVelX( hForeground, GetSpriteVelX(hFox), P_ABSOLUTE );
SetPlaneX( hBackground, 0, P_AUTOMATIC );
SetPlaneX( hMidground, 0, P_AUTOMATIC );
SetPlaneX( hForeground, 0, P_AUTOMATIC );
SetSpriteX( hBear, 0, P_AUTOMATIC );
SetSpriteX( hApple, 0, P_AUTOMATIC );
SetSpriteY( hApple, 0, P_AUTOMATIC );
/*
* once all sprites are processed, display them
*
* If we are using destination transparency instead of source
* transparency, we need to paint the background with the color key
* and then paint our sprites and planes in reverse order.
*
* Since destination transparency will allow you to only write pixels
* on the destination if the transparent color is present, reversing
* the order (so that the topmost bitmaps are drawn first instead of
* list) causes everything to come out ok.
*/
if( bTransDest )
{
gfxFillBack( dwColorKey );
DisplayFrameRate();
DisplaySprite( hBuffer, hApple, GetPlaneX(hForeground) );
DisplaySprite( hBuffer, hBear, GetPlaneX(hForeground) );
DisplaySprite( hBuffer, hFox, GetPlaneX(hForeground) );
DisplayPlane( hBuffer, hForeground );
DisplayPlane( hBuffer, hMidground );
DisplayPlane( hBuffer, hBackground );
}
else
{
DisplayPlane( hBuffer, hBackground );
DisplayPlane( hBuffer, hMidground );
DisplayPlane( hBuffer, hForeground );
DisplaySprite( hBuffer, hFox, GetPlaneX(hForeground) );
DisplaySprite( hBuffer, hBear, GetPlaneX(hForeground) );
DisplaySprite( hBuffer, hApple, GetPlaneX(hForeground) );
DisplayFrameRate();
}
gfxSwapBuffers();
return 0;
} /* NewGameFrame */
第五节 刷新游戏单元
刷新游戏单位的作用是在每一桢刷新游戏单位的状态。请您先阅读一下下面的ProcessInput()函数的部分代码,然后再看看下面这两个例子。
ProcessInput()函数的部分代码:
/*
* ProcessInput
*/
BOOL ProcessInput( SHORT input )
{
static BOOL fBearPlaying = FALSE;
LONG foxSpeedX;
LONG foxSpeedY;
LONG foxX;
LONG foxY;
LONG bearX;
LONG bearY;
LONG appleX;
LONG appleY;
ACTION foxAction;
DIRECTION foxDir;
BOOL cont = TRUE;
foxSpeedX = GetSpriteVelX( hFox );
foxAction = GetSpriteAction( hFox );
foxDir = GetSpriteDirection( hFox );
if( (GetSpriteActive(hFox) == FALSE) && (input != 4209) )
{
input = 0;
}
switch( input )
{
case KEY_DOWN:
if( foxAction == STOP )
{
break;
}
else if( foxAction == STILL )
{
SetSpriteAction( hFox, CROUCH, SAME );
}
else if( foxAction == WALK )
{
SetSpriteAction( hFox, CROUCHWALK, SAME );
}
break;
case KEY_LEFT:
if( foxAction == STOP )
{
break;
}
else if( foxSpeedX == 0 )
{
if( foxAction == STILL )
{
if( foxDir == RIGHT )
{
ChangeSpriteDirection( hFox );
SetPlaneSlideX( hForeground, -C_BOUNDDIF, P_RELATIVE );
SetPlaneSlideX( hMidground, -C_BOUNDDIF, P_RELATIVE );
SetPlaneSlideX( hBackground, -C_BOUNDDIF, P_RELATIVE );
SetPlaneIncremX( hForeground, C_BOUNDINCREM, P_ABSOLUTE );
SetPlaneIncremX( hBackground, C_BOUNDINCREM, P_ABSOLUTE );
SetPlaneIncremX( hMidground, C_BOUNDINCREM, P_ABSOLUTE );
}
else
{
SetSpriteAction( hFox, WALK, LEFT );
SetSpriteSwitch( hFox, C_FOX_WALKSWITCH, P_ABSOLUTE );
SetSpriteVelX( hFox, -C_FOX_XMOVE, P_RELATIVE );
}
}
else if( foxAction == CROUCH )
{
if( foxDir == RIGHT )
{
ChangeSpriteDirection( hFox );
SetPlaneSlideX( hForeground, -C_BOUNDDIF, P_RELATIVE );
SetPlaneSlideX( hMidground, -C_BOUNDDIF, P_RELATIVE );
SetPlaneSlideX( hBackground, -C_BOUNDDIF, P_RELATIVE );
SetPlaneIncremX( hForeground, C_BOUNDINCREM, P_ABSOLUTE );
SetPlaneIncremX( hBackground, C_BOUNDINCREM, P_ABSOLUTE );
SetPlaneIncremX( hMidground, C_BOUNDINCREM, P_ABSOLUTE );
}
else
{
SetSpriteAction( hFox, CROUCHWALK, LEFT );
SetSpriteSwitch( hFox, C_FOX_WALKSWITCH, P_ABSOLUTE );
SetSpriteVelX( hFox, -C_FOX_XMOVE, P_RELATIVE );
}
}
else
{
SetSpriteVelX( hFox, -C_FOX_XMOVE, P_RELATIVE );
}
} else {
SetSpriteVelX( hFox, -C_FOX_XMOVE, P_RELATIVE );
}
break;
case KEY_RIGHT:
.
.
.
case KEY_STOP:
if( foxAction == STOP )
{
break;
}
else if( (foxAction == RUN) || (foxAction == BLURR) )
{
SetSpriteAction( hFox, STOP, SAME );
SetSpriteAccX( hFox, -foxSpeedX / 25, P_ABSOLUTE );
SoundPlayEffect( SOUND_STOP );
} else {
SetSpriteVelX( hFox, 0, P_ABSOLUTE );
}
break;
case KEY_UP:
if( foxAction == STOP )
{
break;
}
else if( foxAction == CROUCH )
{
SetSpriteAction( hFox, STILL, SAME );
}
else if( foxAction == CROUCHWALK )
{
SetSpriteAction( hFox, WALK, SAME );
}
break;
case KEY_JUMP:
if( foxAction == STOP )
{
break;
}
else
if( (foxAction == STILL) || (foxAction == WALK) ||
(foxAction == RUN) || (foxAction == CROUCH) ||
(foxAction == CROUCHWALK) )
{
SetSpriteAction( hFox, JUMP, SAME );
SetSpriteSwitchType( hFox, TIME );
SetSpriteSwitch( hFox, C_FOX_JUMPSWITCH, P_ABSOLUTE );
SetSpriteVelY( hFox, -C_FOX_JUMPMOVE, P_ABSOLUTE );
SetSpriteAccY( hFox, C_UNIT / 2, P_ABSOLUTE );
SoundPlayEffect( SOUND_JUMP );
}
break;
case KEY_THROW:
if( foxAction == STOP )
{
break;
}
else if( (foxAction == STILL) || (foxAction == WALK) ||
(foxAction == RUN) || (foxAction == CROUCH) ||
(foxAction == CROUCHWALK) )
{
SetSpriteAction( hFox, THROW, SAME );
SetSpriteSwitch( hFox, C_FOX_THROWSWITCH, P_ABSOLUTE );
SetSpriteVelX( hFox, 0, P_ABSOLUTE );
SetSpriteSwitchType( hFox, TIME );
}
else if( foxAction == JUMP )
{
SetSpriteAccY( hFox, 0, P_ABSOLUTE );
SetSpriteSwitch( hFox, C_FOX_THROWSWITCH, P_ABSOLUTE );
SetSpriteAction( hFox, JUMPTHROW, SAME );
SetSpriteVelY( hFox, 0, P_ABSOLUTE );
SetSpriteSwitchDone( hFox, FALSE );
SetSpriteSwitchForward( hFox, TRUE );
}
break;
default:
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -