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

📄 gameproc.c

📁 2D即时战略游戏VC源码
💻 C
📖 第 1 页 / 共 4 页
字号:
{
    lpShip->dwKeys = dwControls;

    if( dwControls & KEY_LEFT )
    {
        gbUpdate = TRUE;
        lpShip->cFrame -= 1;
        if( lpShip->cFrame < 0 )
            lpShip->cFrame += MAX_SHIP_FRAME;
    }
    if( dwControls & KEY_RIGHT )
    {
        gbUpdate = TRUE;
        lpShip->cFrame += 1;
        if( lpShip->cFrame >= MAX_SHIP_FRAME )
            lpShip->cFrame -= MAX_SHIP_FRAME;
    }
    if( dwControls & KEY_UP )
    {
        gbUpdate = TRUE;
        lpShip->dVelX += gDirx[lpShip->cFrame] * 10.0 / 1000.0;
        lpShip->dVelY += gDiry[lpShip->cFrame] * 10.0 / 1000.0;
    }
    if( dwControls & KEY_DOWN )
    {
        gbUpdate = TRUE;
        lpShip->dVelX -= gDirx[lpShip->cFrame] * 10.0 / 1000.0;
        lpShip->dVelY -= gDiry[lpShip->cFrame] * 10.0 / 1000.0;
    }
    if( dwControls & KEY_STOP )
    {
        gbUpdate = TRUE;
        lpShip->dVelX = 0.0;
        lpShip->dVelY = 0.0;
    }
    if( !lpShip->bBulletEnable && lpShip->bEnable )
    {
        if( dwControls & KEY_FIRE )
        {
            gbUpdate = TRUE;
            // launch a new bullet
            lpShip->dBulletPosX = (WORD) (gDirx[lpShip->cFrame]*6.0 + 16.0 + lpShip->dPosX);
            lpShip->dBulletPosY = (WORD) (gDiry[lpShip->cFrame]*6.0 + 16.0 + lpShip->dPosY);
            lpShip->dBulletVelX = gDirx[lpShip->cFrame]*500.0/1000.0;
            lpShip->dBulletVelY = gDiry[lpShip->cFrame]*500.0/1000.0;
            lpShip->bBulletEnable = TRUE;
            lpShip->dwBulletFrame = 0;
        }
    }
}

/*
 * SendSync
 *
 * Sends a sync message with the rendevous position. We are using a synchronization technique in
 * which every player informs everyone else where the player is going to be at the end of the 
 * next sync interval. Based on this rendezvous position, everyone tries to move their corresponding
 * ghosts to the rendezvous position by the end of the interval.
 */
void SendSync(LPSHIP lpShip)
{
    gSyncMsg.byShipType = lpShip->byType;
    gSyncMsg.cFrame = lpShip->cFrame;
    gSyncMsg.dPosX  = lpShip->dPosX + lpShip->dVelX*1000;
    gSyncMsg.dPosY  = lpShip->dPosY + lpShip->dVelY*1000;

    SendGameMessage((LPGENERICMSG) &gSyncMsg, DPID_ALLPLAYERS);
}

/*
 * UpdateDisplayStatus
 *
 * Updates the disable timeout. Enables the ship if disable timeout has elapsed.
 */
void UpdateDisplayStatus(LPSHIP lpShip)
{
    DWORD dwTickDiff;
    DWORD dwTickCount;

    // current time
    dwTickCount = timeGetTime();

    // time elapsed since last update
    dwTickDiff =  dwTickCount - lpShip->dwLastTick;

    // timestamp
    lpShip->dwLastTick = dwTickCount;

    // update time-out
    lpShip->iCountDown -= dwTickDiff;

    // time-out ?
    if( lpShip->iCountDown < 0 )
    {
        // get new position and enable our lpShip
        lpShip->dPosX = randInt(0,MAX_SHIP_X);
        lpShip->dPosY = randInt(0,MAX_SHIP_Y);
        lpShip->cFrame = randInt(0, MAX_SHIP_FRAME);
        lpShip->bEnable = TRUE;
    }
}

/*
 * UpdatePosition
 *
 * Updates our ship's position
 */
void UpdatePosition(DPID dpId, LPSHIP lpShip )
{
    int     x,y;
    BYTE    oldxCell, oldyCell, newxCell, newyCell, mask, col, row;
    double  thisTick, totalTick, xtick, ytick;
    DWORD   dwTickCount;
    DWORD   dwTickDiff;

    if( !lpShip->bEnable )
        return;

    // how long has it been since we last updated
    dwTickCount = timeGetTime();
    dwTickDiff = dwTickCount - lpShip->dwLastTick;

    // current timestamp
    lpShip->dwLastTick = dwTickCount;

    oldxCell = (int)(lpShip->dPosX+16.0) >> 4;
    oldyCell = (int)(lpShip->dPosY+16.0) >> 4;

    // compute new position
    lpShip->dPosX += lpShip->dVelX * dwTickDiff;
    lpShip->dPosY += lpShip->dVelY * dwTickDiff;

    newxCell = (int)(lpShip->dPosX+16.0) >> 4;
    newyCell = (int)(lpShip->dPosY+16.0) >> 4;
    if(oldxCell != newxCell)
    {
        // we allow ghosts to pass through the blocks
        if( (dpId == gOurID) && IsHit( newxCell, newyCell ) )
        {
            if( lpShip->dVelX > 0.0 )
                lpShip->dPosX = (oldxCell << 4) + 15 - 16;
            else
                lpShip->dPosX = (oldxCell << 4) - 16;
            lpShip->dVelX = -lpShip->dVelX*0.9;
            newxCell = oldxCell;
            lpShip->bBounced = TRUE;
        }
    }
    if(oldyCell != newyCell)
    {
        // we allow ghosts to pass through the blocks
        if( (dpId == gOurID) && IsHit( newxCell, newyCell ) )
        {
            if( lpShip->dVelY > 0.0 )
                lpShip->dPosY = (oldyCell << 4) + 15 - 16;
            else
                lpShip->dPosY = (oldyCell << 4) - 16;

            lpShip->dVelY = -lpShip->dVelY*0.9;
            lpShip->bBounced = TRUE;
        }
    }

    if( lpShip->dPosX > MAX_SHIP_X )
    {
        lpShip->dPosX = MAX_SHIP_X;
        lpShip->dVelX = -lpShip->dVelX*0.9;
        lpShip->bBounced = TRUE;
    }
    else if ( lpShip->dPosX < 0 )
    {
        lpShip->dPosX =0;
        lpShip->dVelX = -lpShip->dVelX*0.9;
        lpShip->bBounced = TRUE;
    }
    if( lpShip->dPosY > MAX_SHIP_Y )
    {
        lpShip->dPosY = MAX_SHIP_Y;
        lpShip->dVelY = -lpShip->dVelY*0.9;
        lpShip->bBounced = TRUE;
    }
    else if ( lpShip->dPosY < 0 )
    {
        lpShip->dPosY =0;
        lpShip->dVelY = -lpShip->dVelY*0.9;
        lpShip->bBounced = TRUE;
    }    

    if ((dpId == gOurID) && lpShip->bBounced)
    {
        SendSync(lpShip);
    }

    if( !lpShip->bBulletEnable )
        return;

    // update the active bullet
    lpShip->dwBulletFrame += dwTickDiff;
    if( lpShip->dwBulletFrame >= MAX_BULLET_FRAME )
    {
        lpShip->bFiring = FALSE;
        lpShip->bBulletEnable = FALSE;
        return;
    }


    if( lpShip->dBulletVelX != 0.0 )
        xtick = 8.0/lpShip->dBulletVelX;
    else
        xtick = 999999.0;

    if( lpShip->dBulletVelY != 0.0 )
        ytick = 8.0/lpShip->dBulletVelY;
    else
        ytick = 999999.0;

    if( xtick < 0.0 )
        xtick = -xtick;
    if( ytick < 0.0 )
        ytick = -ytick;

    if( xtick < ytick )
        thisTick = xtick;
    else
        thisTick = ytick;
    
    if( thisTick > dwTickDiff )
        thisTick = dwTickDiff;
            
    for( totalTick = 0.0; totalTick < dwTickDiff; )
    {
        totalTick += thisTick;

        lpShip->dBulletPosX += lpShip->dBulletVelX * thisTick;
        lpShip->dBulletPosY += lpShip->dBulletVelY * thisTick;

        if( lpShip->dBulletPosX > MAX_BULLET_X )
        {
            lpShip->dBulletPosX = MAX_BULLET_X;
            lpShip->dBulletVelX = -lpShip->dBulletVelX*0.9;
        }
        else if ( lpShip->dBulletPosX < 0 )
        {
            lpShip->dBulletPosX =0;
            lpShip->dBulletVelX = -lpShip->dBulletVelX*0.9;
        }
        if( lpShip->dBulletPosY > MAX_BULLET_Y )
        {
            lpShip->dBulletPosY = MAX_BULLET_Y;
            lpShip->dBulletVelY = -lpShip->dBulletVelY*0.9;
        }
        else if ( lpShip->dBulletPosY < 0 )
        {
            lpShip->dBulletPosY =0;
            lpShip->dBulletVelY = -lpShip->dBulletVelY*0.9;
        }
    
        // check to see if it hit anything
        x = (int)(lpShip->dBulletPosX + 0.5) + 1;
        y = (int)(lpShip->dBulletPosY + 0.5) + 1;
    
        row = y >> 4;
        col = x >> 4;
        mask = 1 << (col & 0x7);
        col = col >> 3;
        if( gBlocks.bits[row][col] & mask )
        {
            // dwScored a block hit
            gBlockHitMsg.byRow = row;
            gBlockHitMsg.byCol = col;
            gBlockHitMsg.byMask = mask;
            SendGameMessage((LPGENERICMSG) &gBlockHitMsg, DPID_ALLPLAYERS);

            gBlocks.bits[row][col] &= ~mask;
            lpShip->dwScore += 10;
            lpShip->bBulletEnable = FALSE;
            lpShip->bBlockHit = TRUE;
            lpShip->bFiring   = FALSE;
        }
    }
}


/*
 * IsHit
 *
 * Tells if there is a block at (x,y) location
 */
BOOL IsHit( int x, int y )
{
    int col, mask;
    
    // outside screen boundaries?
    if( (x < 0) || (y < 0) || (x >= 40) || (y >= 30) )
        return TRUE;
    
    // look at the block bits
    mask = 1 << (x & 0x7);
    col = x >> 3;
    if( gBlocks.bits[y][col] & mask )
        return TRUE;
    else
        return FALSE;
}

/*
 * InitField
 *
 * Initializes block positions on the field
 */
void InitField(void)
{
    int i, x, y;
    
    // clear all gBlocks
    for(x=0; x<5; x++)
        for(y=0; y<30; y++)
            gBlocks.bits[y][x] = 0;

    // set random gBlocks
    for(i=0; i<400; i++)
    {
        x = randInt(0, 40);
        y = randInt(0, 30);
        if( !setBlock(x, y) ) i--;
    }
}

/*
 * AddBlock
 *
 * Adds a block to the field
 */
void AddBlock(void)
{
    int x,y;

    // maybe add a block?
    if(gbIsHost && gbIsActive && ( randInt( 0, 100 ) > 98 ))
    {
        x = randInt( 0, 40);
        y = randInt( 0, 30);
        if( setBlock( x, y) )
        {
            gAddBlockMsg.byX    = (BYTE) x;
            gAddBlockMsg.byY    = (BYTE) y;
            SendGameMessage((LPGENERICMSG) &gAddBlockMsg, DPID_ALLPLAYERS);
        }
    }
}

/*
 * setBlock
 *
 * Turns on a block
 */
BOOL setBlock( int x, int y )
{
    BYTE  mask, col;

    mask = 1 << (x & 0x7);
    col = x >> 3;
    
    // is Block already set?
    if( gBlocks.bits[y][col] & mask )
        return FALSE;
    
    // set the block and return success
    gBlocks.bits[y][col] |= mask;
    return TRUE;
}

/*
 * AddFrag
 *
 * Turns on a fragment
 */
void AddFrag(LPSHIP lpShip, int offX, int offY)
{
    int i;
    for(i=0; i<64; i++) // find available fragment
    {
        if( !gFrags[i].valid )
        break;
    }
    if( i == 64 )
        return;
    
    
    gFrags[i].dPosX = offX + lpShip->dPosX;
    gFrags[i].dPosY = offY + lpShip->dPosY;
    switch( lpShip->byType )
    {
    case 0: gFrags[i].surf = glpShip0;    break;
    case 1: gFrags[i].surf = glpShip1;    break;
    case 2: gFrags[i].surf = glpShip2;    break;
    case 3: gFrags[i].surf = glpShip3;    break;
    default: DEBUG_OUT(TEXT("Unknown ship type\n")); return;
    }
    gFrags[i].src.top = 32 * ( (int)lpShip->cFrame / 10 ) + offX;
    gFrags[i].src.left = 32 * ( (int)lpShip->cFrame % 10 ) + offY;
    gFrags[i].src.right = gFrags[i].src.left + 8;
    gFrags[i].src.bottom = gFrags[i].src.top + 8;
    gFrags[i].dVelX = ((double)offX - 12.0)/24.0;
    gFrags[i].dVelY = ((double)offY - 12.0)/24.0;
    gFrags[i].valid = TRUE;
}

/*
 * UpdateFragment
 *
 * Updates the position of a fragment
 */
void UpdateFragment(int i)
{
    DWORD   dwTickCount;
    static DWORD   dwTickDiff;
    static DWORD dwLastTick;

    if( i == 0)
    {
        dwTickCount = timeGetTime();
        dwTickDiff = dwTickCount - dwLastTick;
        dwLastTick = dwTickCount;
    }
    
    if( !gFrags[i].valid )
        return;
    
    gFrags[i].dPosX += (int) (gFrags[i].dVelX * dwTickDiff);
    gFrags[i].dPosY += (int) (gFrags[i].dVelY * dwTickDiff);
    if( (gFrags[i].dPosX < 0.0) || (gFrags[i].dPosX >= 632.0) ||
        (gFrags[i].dPosY < 0.0) || (gFrags[i].dPosY >= 472.0) )
    {
        gFrags[i].valid = FALSE;
    }
}

/*
 * DestroyShip
 *
 * Renders a bunch of fragments to show that the ship is destroyed
 */
void DestroyShip( LPSHIP lpShip )
{
    // Set flag for explosion sound
    lpShip->bDeath  = TRUE;

    // add ship fragments
    AddFrag(lpShip, 0, 0);
    AddFrag(lpShip, 8, 0);
    AddFrag(lpShip, 16, 0);
    AddFrag(lpShip, 24, 0);
    AddFrag(lpShip, 0, 8);
    AddFrag(lpShip, 8, 8);
    AddFrag(lpShip, 16, 8);
    AddFrag(lpShip, 24, 8);
    AddFrag(lpShip, 0, 16);
    AddFrag(lpShip, 8, 16);
    AddFrag(lpShip, 16, 16);
    AddFrag(lpShip, 24, 16);
    AddFrag(lpShip, 0, 24);
    AddFrag(lpShip, 8, 24);
    AddFrag(lpShip, 16, 24);
    AddFrag(lpShip, 24, 24);

    // Play explosion sound
    ProcessSoundFlags(lpShip);
}

/*
 * UpdateFrame
 *
 * Refreshes the screen
 */
BOOL UpdateFrame( void )
{
    int i;
    DWORD dwTickCount;
    SHIP  ship;
    DWORD dwSize;
    HRESULT hr;
    static dwSyncLastTick = 0;
    static dwUpdateLastTick = 0;
    
    switch( gnProgramState )
    {
    case PS_ACTIVE:
        // DINPUT: use DirectInput to read game-play keys
        DI_ReadKeys();

        // get our local data
        dwSize = sizeof(ship);
        hr = DPlayGetPlayerData(gOurID, &ship, &dwSize, DPGET_LOCAL);
        if (FAILED(hr))
        {
            wsprintf(gDebugBuff, TEXT("Get Player local data failed for id %d\n"), gOurID);

⌨️ 快捷键说明

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