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

📄 gameproc.c

📁 2D即时战略游戏VC源码
💻 C
📖 第 1 页 / 共 4 页
字号:
        wsprintf(gDebugBuff, TEXT("Get Player local data failed for id %d\n"), gOurID);
        DEBUG_OUT(gDebugBuff);
        goto FAIL;
    }

    // blt everything in reverse order if we are doing destination transparency
    // calculate dwScore string
    dwScorebuf[0] = (BYTE)ship.dwScore/100000 + '0';
    rem = ship.dwScore % 100000;
    dwScorebuf[1] = rem/10000 + '0';
    rem = ship.dwScore % 10000;
    dwScorebuf[2] = rem/1000 + '0';
    rem = ship.dwScore % 1000;
    dwScorebuf[3] = rem/100 + '0';
    rem = ship.dwScore % 100;
    dwScorebuf[4] = rem/10 + '0';
    rem = ship.dwScore % 10;
    dwScorebuf[5] = rem + '0';
    dwScorebuf[6] = '\0';

    bltScore(dwScorebuf, 8, 8);

    // save ship data
    hr = DPlaySetPlayerData(gOurID, &ship, sizeof(ship), DPSET_LOCAL);
    if (FAILED(hr))
    {
        ShowError(IDS_DPLAY_ERROR_SPLD);
        goto FAIL;
    }

    return TRUE;

FAIL:
    // failed
    return FALSE;
}

/*
 * DrawBlock
 *
 * Renders a block
 */
void DrawBlock( int x, int y )
{
    RECT    src;
    
    src.top = 0;
    src.left = 224;
    src.right = src.left + 16;
    src.bottom = src.top + 16;
    bltObject( x << 4, y << 4, glpNum, &src, DDBLTFAST_SRCCOLORKEY );
}

/*
 * DrawShip
 *
 * Renders a ship
 */
void DrawShip( LPSHIP lpShip )
{
    RECT    src;
    LPDIRECTDRAWSURFACE surf;

    src.top = 32 * (lpShip->cFrame / 10 );
    src.left = 32 * (lpShip->cFrame % 10 );
    src.right = src.left + 32;
    src.bottom = src.top + 32;
    switch( lpShip->byType )
    {
    case 0: surf = glpShip0; break;
    case 1: surf = glpShip1; break;
    case 2: surf = glpShip2; break;
    case 3: surf = glpShip3; break;
    default: DEBUG_OUT(TEXT("Ship type not specified\n")); return;
    }
    bltObject((int)lpShip->dPosX, (int)lpShip->dPosY, surf, &src, DDBLTFAST_SRCCOLORKEY );
}

/*
 * DrawBullet
 *
 * Renders a bullet 
 */
void DrawBullet( LPSHIP lpShip )
{
    RECT    src;
    
    src.top = BULLET_Y;
    src.left = BULLET_X + (lpShip->byType)*4;
    src.right = src.left + 3;
    src.bottom = src.top + 3;
    bltObject((int)lpShip->dBulletPosX, (int)lpShip->dBulletPosY, glpNum, &src, DDBLTFAST_SRCCOLORKEY );
}

/*
 * DrawFragments
 *
 * Renders the fragments
 */

void DrawFragments( void )
{
    int     i;
    
    for(i=0; i<64; i++)
    {
        if( gFrags[i].valid )
        {
            bltObject((int)gFrags[i].dPosX, (int)gFrags[i].dPosY, gFrags[i].surf,
                &(gFrags[i].src), DDBLTFAST_SRCCOLORKEY );
        }
    }
}

/*
 * ReceiveGameMessages
 *
 * Checks if there are any messages for us and receives them
 */
HRESULT ReceiveMessages( void )
{
    DPID                idFrom, idTo;
    LPVOID              lpvMsgBuffer;
    DWORD               dwMsgBufferSize;
    HRESULT             hr;

    // read all messages in queue
    dwMsgBufferSize = gdwReceiveBufferSize;
    lpvMsgBuffer = glpvReceiveBuffer;
    
    while (TRUE)
    {
        // see what's out there
        idFrom = 0;
        idTo = 0;

        hr = DPlayReceive(&idFrom, &idTo, DPRECEIVE_ALL, lpvMsgBuffer, &dwMsgBufferSize);
        if (hr == DPERR_BUFFERTOOSMALL)
        {
            if (lpvMsgBuffer == NULL)
            {
                lpvMsgBuffer = GlobalAllocPtr(GHND, dwMsgBufferSize);
                if (lpvMsgBuffer == NULL)
                    return (DPERR_NOMEMORY);
                glpvReceiveBuffer = lpvMsgBuffer;
                gdwReceiveBufferSize = dwMsgBufferSize;
            }
            else if (dwMsgBufferSize > gdwReceiveBufferSize)
            {
                lpvMsgBuffer = GlobalReAllocPtr(lpvMsgBuffer, dwMsgBufferSize, 0);
                if (lpvMsgBuffer == NULL)
                    return (DPERR_NOMEMORY);
                glpvReceiveBuffer = lpvMsgBuffer;
                gdwReceiveBufferSize = dwMsgBufferSize;
            }
        }
        else if ((hr == DP_OK) && 
                 ((dwMsgBufferSize >= sizeof(GENERICMSG)) || 
                  (dwMsgBufferSize >= sizeof(DPMSG_GENERIC))))
        {
            if (idFrom == DPID_SYSMSG)
            {
                DoSystemMessage((LPDPMSG_GENERIC) lpvMsgBuffer, dwMsgBufferSize, idFrom, idTo);
            }
            else
            {
                DoApplicationMessage((LPGENERICMSG) lpvMsgBuffer, dwMsgBufferSize, idFrom, idTo);
            }
        }
        else
            break;
    };

    return hr;
}

/*
 * DoSystemMessage
 *
 * Evaluates system messages and performs appropriate actions
 */
void DoSystemMessage( LPDPMSG_GENERIC lpMsg, DWORD dwMsgSize, DPID idFrom, DPID idTo )
{
    switch( lpMsg->dwType)
    {
    case DPSYS_CREATEPLAYERORGROUP:
        {
            LPDPMSG_CREATEPLAYERORGROUP lpAddMsg = (LPDPMSG_CREATEPLAYERORGROUP) lpMsg;

            if( gbIsHost)
            {
                gHostMsg.Blocks = gBlocks;
                SendGameMessage((LPGENERICMSG) &gHostMsg, lpAddMsg->dpId);
            }
        }
        break;

    case DPSYS_DESTROYPLAYERORGROUP:
        {
            LPSHIP lpShip;
            LPDPMSG_DESTROYPLAYERORGROUP lpDestroyMsg = (LPDPMSG_DESTROYPLAYERORGROUP) lpMsg;

            if ((sizeof(SHIP) != lpDestroyMsg->dwLocalDataSize) || 
                (NULL == lpDestroyMsg->lpLocalData))
                break;

            lpShip = lpDestroyMsg->lpLocalData;
            ReleasePlayerLocalSoundData(lpShip);
        }
        break;

    case DPSYS_HOST:
        {           
            gbIsHost = TRUE;            
            UpdateTitle();
        }

        break;

    case DPSYS_SESSIONLOST:
        // inform user that session was lost
        ShowError(IDS_DPLAY_ERROR_SL);
        gbSessionLost = TRUE;
        break;
    }
}

/*
 * DoApplicationMessage
 *
 * Evaluates an application message and performs appropriate actions
 */
void DoApplicationMessage( LPGENERICMSG lpMsg, DWORD dwMsgSize, DPID idFrom, DPID idTo )
{        
    HRESULT hr;

    switch( lpMsg->byType )
    {
    case MSG_HOST:
        {
            LPHOSTMSG       lpHost;

            if( !gbIsHost )
            {
                lpHost = (LPHOSTMSG) lpMsg;
                // receive the field layout
                gBlocks = lpHost->Blocks;

                // have host initializtion at this point
                gbHaveHostInit = TRUE;
                
                // start updating screen
                gbIsActive = TRUE;
            }
        }
        break;

    case MSG_BLOCKHIT:
        {
            LPBLOCKHITMSG   lpBlockHit;

            lpBlockHit = (LPBLOCKHITMSG) lpMsg;
            gBlocks.bits[lpBlockHit->byRow][lpBlockHit->byCol] &= ~lpBlockHit->byMask;
        }
        break;

    case MSG_ADDBLOCK:
        {
            LPADDBLOCKMSG   lpAddBlock;

            lpAddBlock = (LPADDBLOCKMSG) lpMsg;
            setBlock( lpAddBlock->byX, lpAddBlock->byY);
        }
        break;

    case MSG_SHIPHIT:
        {
            LPSHIPHITMSG    lpShipHit = (LPSHIPHITMSG) lpMsg;
            SHIP ship;
            DWORD dwSize;

            dwSize = sizeof(SHIP);
             // get player local data
            hr = DPlayGetPlayerData(lpShipHit->Id, &ship, &dwSize, DPGET_LOCAL);
            if (FAILED(hr))
                return;

            // no player data yet
            if (0 == dwSize)
                return;

            if (!ship.bIgnore) 
            {
                // explode the ship on our screen
                DestroyShip(&ship);

                // turn it off
                ship.bEnable = FALSE;
                ship.bBulletEnable = FALSE;

                // if it is us
                if (lpShipHit->Id == gOurID)
                {
                    // set our hide time-out
                    ship.iCountDown = HIDE_TIMEOUT;
                    ship.dwLastTick = timeGetTime();
                    // let the world know that we are dead
                    gShipHitMsg.Id = gOurID;
                    SendGameMessage((LPGENERICMSG) &gShipHitMsg, DPID_ALLPLAYERS);                  
                }
            }
            // update player local data
            DPlaySetPlayerData(lpShipHit->Id, &ship, sizeof(ship), DPSET_LOCAL);
        }
        break;

    case MSG_CONTROL:
        {
            LPCONTROLMSG lpControlMsg;
            SHIP ship;
            DWORD dwSize;

            lpControlMsg = (LPCONTROLMSG) lpMsg;
            dwSize = sizeof(SHIP);
            // get player local data
            hr = DPlayGetPlayerData(idFrom, &ship, &dwSize, DPGET_LOCAL);
            if (FAILED(hr))
                return;

            // no player data yet
            if (0 == dwSize)
                return;

            // update its State
            UpdateState(&ship, (DWORD)lpControlMsg->byState);

            // save it back
            DPlaySetPlayerData(idFrom, &ship, dwSize, DPSET_LOCAL);
        }
        break;

    case MSG_SYNC:
        {
            LPSYNCMSG lpSyncMsg;
            SHIP ship;
            DWORD dwSize;

            lpSyncMsg = (LPSYNCMSG) lpMsg;
            dwSize = sizeof(SHIP);
            // get player local data
            hr = DPlayGetPlayerData(idFrom, &ship, &dwSize, DPGET_LOCAL);
            if (FAILED(hr))
                return;

            // we are seeing this player for the first time
            // so do the initialization
            if (0 == dwSize)
            {
                ZeroMemory(&ship, sizeof(ship));

                // initialize sound buffers
                InitPlayerLocalSoundData(&ship);

                ship.byType = lpSyncMsg->byShipType;
                ship.dPosX = lpSyncMsg->dPosX;
                ship.dPosY = lpSyncMsg->dPosY;
                ship.cFrame = lpSyncMsg->cFrame;
                ship.dwLastTick = timeGetTime();
                ship.bEnable = TRUE;
            }
            
            if (ship.bEnable)
            {
                // head towards rendezvous location (accelerate/decelerate as necessary)
                ship.dVelX = (lpSyncMsg->dPosX - ship.dPosX)/1000;
                ship.dVelY = (lpSyncMsg->dPosY - ship.dPosY)/1000;
                ship.cFrame = lpSyncMsg->cFrame;
            }
            else if (!ship.bIgnore)
            // Ship is alive, but we just don't know it.
            // So, display it at the rendezvous location.
            {
                ship.dPosX = lpSyncMsg->dPosX;
                ship.dPosY = lpSyncMsg->dPosY;
                ship.cFrame = lpSyncMsg->cFrame;
                ship.dwLastTick = timeGetTime();
                ship.bEnable = TRUE;
            }

            // save it back
            DPlaySetPlayerData(idFrom, &ship, sizeof(ship), DPSET_LOCAL);
        }
        break;

    default:
        {
            wsprintf(gDebugBuff, TEXT("Unknown message type %d\n"), lpMsg->byType);
            DEBUG_OUT( gDebugBuff );
        }
        break;
    }
}

/*
 * SendGameMessage
 *
 * Sends a message to specified player(s)
 */
void SendGameMessage( LPGENERICMSG lpMsg, DPID idTo )
{
    int             nBytes;
    DWORD           dwFlags = 0;

    if (gbSessionLost)
    {
        // no sends when we are not in the session
        return;
    }

    switch( lpMsg->byType )
    {
    case MSG_HOST:
        nBytes = sizeof( HOSTMSG );
        dwFlags = DPSEND_GUARANTEED;
        break;

    case MSG_BLOCKHIT:
        nBytes = sizeof( BLOCKHITMSG );
        break;

    case MSG_SHIPHIT:
        nBytes = sizeof( SHIPHITMSG );
        break;

    case MSG_ADDBLOCK:
        nBytes = sizeof( ADDBLOCKMSG );
        break;

    case MSG_CONTROL:
        nBytes = sizeof( CONTROLMSG );
        break;

    case MSG_SYNC:
        nBytes = sizeof( SYNCMSG );
        break;

    default:
        return;
    }

    if (gbReliable)
    {
        dwFlags = DPSEND_GUARANTEED;
    }

    // Send the message to the relevant player(s)
    DPlaySend(gOurID, idTo, dwFlags, (LPVOID)lpMsg, nBytes);    
}

/*
 * CleanupComm
 *
 * Cleans up communication stuff
 */
void CleanupComm(void)
{
    HRESULT hr;

    //free up all the local sound buffers
    ReleaseLocalData();

    // free the receive buffer
    if (glpvReceiveBuffer)
    {
        GlobalFreePtr(glpvReceiveBuffer);
        glpvReceiveBuffer = NULL;
    }

    // delete our player
    if( gOurID ) 
    {
        hr = DPlayDestroyPlayer(gOurID);
        if (FAILED(hr))
        {
            ShowError(IDS_DPLAY_ERROR_DP);
        }
        gOurID = 0;
    }

    // cleanup directplay objects
    hr = DPlayClose();
    hr = DPlayRelease();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -