⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chapter7.txt

📁 系统全面的介绍WINDOWS中游戏的编程
💻 TXT
📖 第 1 页 / 共 5 页
字号:
	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 + -