📄 gameproc.c
字号:
DEBUG_OUT(gDebugBuff);
goto FAIL;
}
if (!ship.bEnable)
{
// update disable timeout and display status
UpdateDisplayStatus(&ship);
}
else
{
// process any change in game controls
ProcessUserInput(&ship);
dwTickCount = timeGetTime();
// synchronize if it's time
if (gbIsActive && ((dwTickCount - dwSyncLastTick) > SYNC_INTERVAL))
{
SendSync(&ship);
dwSyncLastTick = dwTickCount;
}
// if our player changed any keys, let everyone know
if (gbUpdate)
{
// control the number of packets we send
if ((dwTickCount - dwUpdateLastTick) > UPDATE_INTERVAL)
{
// let others know
gControlMsg.byState = (BYTE) gdwKeys;
SendGameMessage((LPGENERICMSG) &gControlMsg, DPID_ALLPLAYERS);
dwUpdateLastTick = dwTickCount;
}
}
}
// save ship data as RenderPlayerCB reads stored data
hr = DPlaySetPlayerData(gOurID, &ship, sizeof(ship), DPSET_LOCAL);
if (FAILED(hr))
{
ShowError(IDS_DPLAY_ERROR_SPLD);
goto FAIL;
}
// update fragments
for(i=0; i<64; i++)
UpdateFragment(i);
// add a block
if (!gbNoField)
AddBlock();
// render everything
if (!DrawScreen())
{
goto FAIL;
}
break;
case PS_REST:
if( gbHaveHostInit )
{
SetGamePalette();
gnProgramState = PS_ACTIVE;
}
break;
}
// success
return TRUE;
FAIL:
// failed
return FALSE;
}
/*
*FUNCTION: ProcessSoundFlags
*
*PARAMETERS:
* lpShip: Points to a ship structure (originally retrieved from
* GetPlayerData) in RenderPlayer.
*
*NOTES: All y-coordinates must be made negative, because the
* 3D Sound API's use an opposite coordinate system than
* the screen.
*/
void ProcessSoundFlags(LPSHIP lpShip)
{
int i;
BOOL bStart[MAX_SOUNDS]; //flags, used so we can
BOOL bStop [MAX_SOUNDS];
if (!gbSoundInitialized)
return;
//if one is NULL, so are the other ones and we aren't initialized yet.
for (i=0; i<MAX_SOUNDS; i++)
{
if (lpShip->lpDirectSoundBuffer[i]==NULL)
return;
}
//set all our temporary flags to FALSE.
for (i=0; i<MAX_SOUNDS; i++)
{
bStart[i] = FALSE;
bStop[i] = FALSE;
}
if (lpShip->dwKeys & KEY_ENGINEOFF)
{
bStop[SENGINE] = TRUE;
lpShip->bEngineRunning = FALSE;
}
if (lpShip->dwKeys & (KEY_UP | KEY_DOWN))
{
if (!lpShip->bEngineRunning) //turn on engine
{
bStart[SENGINE] = TRUE;
if (!lpShip->bMoving) //"fire-up-engine" sound
{
bStart[SSTART] = TRUE;
IDirectSound3DBuffer_SetPosition(lpShip->lpDirectSound3DBuffer[SSTART],
P2M(lpShip->dPosX - 320),
-P2M(lpShip->dPosY - 240),
D3DVAL(0),
DS3D_DEFERRED);
bStart[SSTART] =TRUE;
lpShip->bMoving =TRUE;
}
lpShip->bEngineRunning = TRUE;
}
}
if (lpShip->bMoving)
{
IDirectSound3DBuffer_SetPosition(lpShip->lpDirectSound3DBuffer[SENGINE],
P2M(lpShip->dPosX - 320),
-P2M(lpShip->dPosY - 240),
D3DVAL(0),
DS3D_DEFERRED);
IDirectSound3DBuffer_SetVelocity(lpShip->lpDirectSound3DBuffer[SENGINE],
D3DVAL(lpShip->dVelX * 10), //exagerater vel
D3DVAL(lpShip->dVelY * 10),
D3DVAL(0),
DS3D_DEFERRED);
}
if (lpShip->dwKeys & KEY_STOP)
{
if (lpShip->bMoving)
{
IDirectSound3DBuffer_SetPosition(lpShip->lpDirectSound3DBuffer[SSTOP],
P2M(lpShip->dPosX - 320),
-P2M(lpShip->dPosY - 240),
D3DVAL(0),
DS3D_DEFERRED);
bStart[SSTOP] = TRUE;
bStop[SENGINE] = TRUE;
lpShip->bEngineRunning = FALSE;
lpShip->bMoving = FALSE;
}
}
if (lpShip->dwKeys & KEY_FIRE)
{
if (!lpShip->bFiring)
{
IDirectSound3DBuffer_SetPosition(lpShip->lpDirectSound3DBuffer[BFIRE],
P2M(lpShip->dPosX - 320),
-P2M(lpShip->dPosY - 240),
D3DVAL(0),
DS3D_DEFERRED);
bStart[BFIRE] = TRUE;
lpShip->bFiring = TRUE;
}
}
if (lpShip->bBlockHit)
{
IDirectSound3DBuffer_SetPosition(lpShip->lpDirectSound3DBuffer[LBOOM],
P2M(lpShip->dBulletPosX - 320),
-P2M(lpShip->dBulletPosY - 240),
D3DVAL(0),
DS3D_DEFERRED);
bStart[LBOOM] = TRUE;
lpShip->bBlockHit = FALSE;
}
if (lpShip->bBounced)
{
IDirectSound3DBuffer_SetPosition(lpShip->lpDirectSound3DBuffer[SBOUNCE],
P2M(lpShip->dPosX - 320),
-P2M(lpShip->dPosY - 240),
D3DVAL(0),
DS3D_DEFERRED);
bStart[SBOUNCE] = TRUE;
lpShip->bBounced = FALSE;
}
if (lpShip->bDeath)
{
bStop [BFIRE] = TRUE;
bStop [SBOUNCE] = TRUE;
bStop [SSTOP] = TRUE;
bStop [SSTART] = TRUE;
bStop [SENGINE] = TRUE;
bStart[SBOOM] = TRUE;
lpShip->bDeath = FALSE; //turn off sound flag.
}
//stop, update, and start sounds.
for (i=0; i<MAX_SOUNDS; i++)
{
if (bStop[i])
{
IDirectSoundBuffer_Stop(lpShip->lpDirectSoundBuffer[i]);
bStart[i] = FALSE;
}
}
IDirectSound3DListener_CommitDeferredSettings(glpDirectSound3DListener);
for (i=0; i<MAX_SOUNDS; i++)
{
if (bStart[i])
{
IDirectSoundBuffer_SetCurrentPosition(lpShip->lpDirectSoundBuffer[i], 0);
if (DSERR_BUFFERLOST==IDirectSoundBuffer_Play(lpShip->lpDirectSoundBuffer[i],
0,
0,
(i==SENGINE) ? DSBPLAY_LOOPING : 0))
{
WaveReload(gSoundEffect[i]);
}
}
}
lpShip->dwKeys = 0;
};
/*
* RenderPlayerCB
*
* Renders a ship in its current state. Also checks if we hit the ship and informs
* the ship that it has been destroyed.
*/
BOOL WINAPI RenderPlayerCB(DPID dpId, DWORD dwPlayerType, LPCDPNAME lpName,
DWORD dwFlags, LPVOID lpContext)
{
SHIP ship, ourShip;
DWORD dwSize = sizeof(ship);
BOOL bHit = FALSE;
HRESULT hr;
DWORD dwTickCount;
// get ship data
hr = DPlayGetPlayerData(dpId, &ship, &dwSize, DPGET_LOCAL);
if (FAILED(hr))
{
wsprintf(gDebugBuff, TEXT("Get Player local data failed for id %d\n"), dpId);
DEBUG_OUT(gDebugBuff);
goto FAIL;
}
// no player data yet
if (0 == dwSize)
return TRUE;
// ignore current ship ?
if (ship.bIgnore)
{
// if this ship was being ignored, update ignore time-out
// A time-out is used here to ensure that this ship doesn't get ignored
// forever on our screen in case the destroy message was dropped.
dwTickCount = timeGetTime();
ship.iCountDown -= dwTickCount - ship.dwLastTick;
ship.dwLastTick = dwTickCount;
if( ship.iCountDown < 0 )
{
ship.bIgnore = FALSE;
}
// save ship data
hr = DPlaySetPlayerData(dpId, &ship, sizeof(ship), DPSET_LOCAL);
if (FAILED(hr))
{
ShowError(IDS_DPLAY_ERROR_SPLD);
goto FAIL;
}
// we are ignoring this ship, so just bail
return TRUE;
}
// bail, if ship is disabled
if (!ship.bEnable) return TRUE;
// update ship's position
UpdatePosition(dpId, &ship);
// get our player data to compare with others
dwSize = sizeof(ship);
hr = DPlayGetPlayerData(gOurID, &ourShip, &dwSize, DPGET_LOCAL);
if (FAILED(hr))
{
wsprintf(gDebugBuff, TEXT("Get Player local data failed for id %d\n"), dpId);
DEBUG_OUT(gDebugBuff);
goto FAIL;
}
// check if our bullet hit the current ship
if((dpId != gOurID) && ourShip.bBulletEnable && ship.bEnable)
{
if( (ourShip.dBulletPosX > ship.dPosX) &&
(ourShip.dBulletPosX < (ship.dPosX + 32.0) ) &&
(ourShip.dBulletPosY > ship.dPosY) &&
(ourShip.dBulletPosY < (ship.dPosY + 32.0) ) )
{
// hasta-la-vista baby
DestroyShip(&ship);
// we nailed it
bHit = TRUE;
// turn off ship locally
ship.bEnable = FALSE;
// temporarily ignore ship until we get a response
ship.bIgnore = TRUE;
// set its ignore time-out
ship.iCountDown = HIDE_TIMEOUT;
// time-stamp
ship.dwLastTick = timeGetTime();
// turn our bullet off
ship.bBulletEnable = FALSE;
// update our score
ourShip.dwScore += 1000;
// save our score
hr = DPlaySetPlayerData(gOurID, &ourShip, sizeof(ourShip), DPSET_LOCAL);
if (FAILED(hr))
{
ShowError(IDS_DPLAY_ERROR_SPLD);
goto FAIL;
}
}
}
// render the ship
if (ship.bBulletEnable) DrawBullet(&ship);
if (ship.bEnable) DrawShip(&ship);
ProcessSoundFlags(&ship);
// save ship data
hr = DPlaySetPlayerData(dpId, &ship, sizeof(ship), DPSET_LOCAL);
if (FAILED(hr))
{
ShowError(IDS_DPLAY_ERROR_SPLD);
goto FAIL;
}
// inform the player
if (bHit)
{
gShipHitMsg.Id = dpId;
SendGameMessage((LPGENERICMSG) &gShipHitMsg, dpId);
}
// success
return TRUE;
FAIL:
// failed
return FALSE;
}
/*
* DrawScreen
*
* Renders the current frame
*/
BOOL DrawScreen( void )
{
BYTE mask, col;
int x, y;
HRESULT hr;
// clear screen
EraseScreen();
// render players
hr = DPlayEnumPlayers(NULL, RenderPlayerCB, NULL, 0);
if (FAILED(hr))
{
ShowError(IDS_DPLAY_ERROR_EP);
goto FAIL;
}
// render field
for( y=0; y<30; y++)
{
for( x=0; x<40; x++)
{
mask = 1 << (x & 0x7);
col = x >> 3;
if( gBlocks.bits[y][col] & mask )
DrawBlock( x, y );
}
}
// render score
if (!DrawScore())
{
goto FAIL;
}
// render fragments
DrawFragments();
// render frame rate
if( gbShowFrameCount )
DisplayFrameRate();
// show
FlipScreen();
// success
return TRUE;
FAIL:
return FALSE;
}
/*
* DisplayFrameRate
*
* Renders current frame rate
*/
void DisplayFrameRate( void )
{
DWORD time2;
char buff[256];
static DWORD dwFrames;
gdwFrameCount++;
time2 = timeGetTime() - gdwFrameTime;
if( time2 > 1000 )
{
dwFrames = (gdwFrameCount*1000)/time2;
gdwFrameTime = timeGetTime();
gdwFrameCount = 0;
}
if( dwFrames == 0 )
{
return;
}
if (dwFrames != gdwFramesLast)
{
gdwFramesLast = dwFrames;
}
if( dwFrames > 99 )
{
dwFrames = 99;
}
buff[0] = (char)((dwFrames / 10) + '0');
buff[1] = (char)((dwFrames % 10) + '0');
buff[2] = '\0';
bltScore(buff, 295, 10);
}
/*
* DrawScore
*
* Renders our current score
*/
BOOL DrawScore( void )
{
SHIP ship;
DWORD dwSize;
char dwScorebuf[11];
int rem;
HRESULT hr;
dwSize = sizeof(ship);
hr = DPlayGetPlayerData(gOurID, &ship, &dwSize, DPGET_LOCAL);
if (FAILED(hr))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -