?? game.cpp
字號:
SAFE_RELEASE( m_pddsFrontBuffer );
SAFE_RELEASE( m_pDD );
}
void CGame::FlipScreen()
{
HRESULT hr;
if( m_bFullScreen )
hr = m_pddsFrontBuffer->Flip( NULL, DDFLIP_WAIT );
else
{
hr = m_pddsFrontBuffer->Blt( &m_rcWindow, m_pddsBackBuffer,
NULL, DDBLT_WAIT, NULL );
}
if( hr == DDERR_SURFACELOST )
RestoreSurfaces();
}
LPDIRECTDRAWSURFACE CGame::DDCreateSurface( int width, int height )
{
DDSURFACEDESC ddsd;
ZeroMemory( &ddsd, sizeof(ddsd) );
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = width;
ddsd.dwHeight = height;
LPDIRECTDRAWSURFACE pdds;
if( FAILED(m_pDD->CreateSurface( &ddsd, &pdds, NULL )) )
return NULL;
return pdds;
}
void CGame::RestoreSurfaces()
{
m_pddsBackBuffer->Restore();
m_pddsFrontBuffer->Restore();
for( int i = 0; i < NUM_BITMAPS; i ++ )
m_pBmpList[i]->Restore();
DDReLoadBitmap( m_pBmpList[0], "graphics\\tile.bmp" ); //物體
DDReLoadBitmap( m_pBmpList[1], "graphics\\player1.bmp" );
DDReLoadBitmap( m_pBmpList[2], "graphics\\bullet.bmp" );
DDReLoadBitmap( m_pBmpList[3], "graphics\\explode1.bmp" ); //爆炸形狀1
DDReLoadBitmap( m_pBmpList[4], "graphics\\explode2.bmp" ); //爆炸形狀2
DDReLoadBitmap( m_pBmpList[5], "graphics\\enemy.bmp" );
DDReLoadBitmap( m_pBmpList[6], "graphics\\bonus.bmp" );
DDReLoadBitmap( m_pBmpList[7], "graphics\\bore.bmp" );
DDReLoadBitmap( m_pBmpList[8], "graphics\\misc.bmp" );
DDReLoadBitmap( m_pBmpList[9], "graphics\\player2.bmp" );
DDReLoadBitmap( m_pBmpList[10], "graphics\\splash.bmp" );
DDReLoadBitmap( m_pBmpList[11], "graphics\\gameover.bmp" );
DDReLoadBitmap( m_pBmpList[12], "graphics\\flag.bmp" );
DDReLoadBitmap( m_pBmpList[13], "graphics\\num.bmp" );
DDReLoadBitmap( m_pBmpList[14], "graphics\\shield.bmp" ); //保護體
}
void CGame::DDClear( RECT* prc, DWORD dwFillColor )
{
DDBLTFX ddbfx;
ZeroMemory( &ddbfx, sizeof(ddbfx) );
ddbfx.dwSize = sizeof(ddbfx);
ddbfx.dwFillColor = dwFillColor;
m_pddsBackBuffer->Blt( prc, NULL, NULL,
DDBLT_COLORFILL | DDBLT_WAIT, &ddbfx );
}
void CGame::ProcessInput()
{
static DWORD lastTick = timeGetTime();
DWORD time = timeGetTime() - lastTick;
CBullet* bullet;
float x, y;
DIRECTION dir;
int surface;
int i, j, k;
lastTick = timeGetTime();
// process player's input
WORD input[2];
m_DirectInput.GetKey( input[0], input[1] );
for( k = 0; k < 2; k ++ )
{
if( !m_player[k].m_active )
continue;
x = m_player[k].m_x;
y = m_player[k].m_y;
dir = m_player[k].m_dir;
if( !m_player[k].m_bBoring && m_gameState != GS_OVER )
{
if( m_player[k].ProcessInput(input[k], time) )
m_DirectSound.Play( EFFECT_FIRE );
}
surface = m_plane.GetSurface( m_player[k] );
if( surface != OBJ_NULL &&
surface != OBJ_TREE )
{
m_player[k].m_x = x;
m_player[k].m_y = y;
m_player[k].m_dir = dir;
}
if( m_player[k].HitTest( m_player[!k], (int)x, (int)y ) )
{
// two players hit together
m_player[k].m_x = x;
m_player[k].m_y = y;
m_player[k].m_dir = dir;
}
for( i = 0; i < m_nMaxEnemys; i ++ )
{
if( m_player[k].HitTest( m_enemy[i], (int)x, (int)y ) )
{
// we hit the enemy
m_player[k].m_x = x;
m_player[k].m_y = y;
m_player[k].m_dir = dir;
break;
}
}
if( m_player[k].HitTest( m_bonus ) )
{
// we hit the bonus
EatBonus( m_player[k] );
}
// bullet
for( j = 0; j < 2; j ++ )
{
bullet = &m_player[k].m_bullet[j];
if( !bullet->m_active )
continue;
if( !bullet->Move() )
{
bullet->m_active = FALSE;
continue;
}
int surface = m_plane.HitSurface( *bullet, m_player[k].m_type>=3 );
if( surface == OBJ_BRICK )
{
bullet->m_active = FALSE;
Explode( *bullet );
}
else if( surface == OBJ_CONCRETE )
{
bullet->m_active = FALSE;
Explode( *bullet );
m_DirectSound.Play( EFFECT_HIT );
}
else if( surface == OBJ_HAWK )
{
bullet->m_active = FALSE;
Explode( *bullet, TRUE );
m_DirectSound.Play( EFFECT_EXPLODE );
m_gameState = GS_OVER;
}
if( !m_bSingle &&
bullet->HitTest( m_player[!k] ) )
{
// We hit the other player
bullet->m_active = FALSE;
if( !m_player[!k].m_bShield )
m_player[!k].Lock();
}
for( i = 0; i < m_nMaxEnemys; i ++ )
{
if( !m_enemy[i].m_bShield && !m_enemy[i].m_bBoring &&
bullet->HitTest( m_enemy[i] ) )
{
// our bullet hit the enemy
bullet->m_active = FALSE;
Explode( *bullet );
if( m_enemy[i].m_bBonus )
{
m_enemy[i].m_bBonus = FALSE;
BoreBonus();
}
if( m_enemy[i].m_type == 2 )
{
if( --m_enemy[i].m_level < 0 )
m_enemy[i].m_active = FALSE;
}
else
m_enemy[i].m_active = FALSE;
if( !m_enemy[i].m_active )
{
// the enemy is dead
Explode( m_enemy[i], TRUE );
m_DirectSound.Play( EFFECT_EXPLODE );
m_nEnemys --;
m_player[k].m_nScore += (m_enemy[i].m_type+1) * 100;
}
break;
}
else if( bullet->HitTest( m_enemy[i].m_bullet[0] ) )
{
// our bullet hit the enemy's
bullet->m_active = FALSE;
m_enemy[i].m_bullet[0].m_active = FALSE;
break;
}
}
}
}
if( !m_bSingle )
{
for( i = 0; i < 2; i ++ )
for( j = 0; j < 2; j ++ )
{
if( m_player[0].m_bullet[i].HitTest(
m_player[1].m_bullet[j] ) )
{
// two players' bullet hit together
m_player[0].m_bullet[i].m_active = FALSE;
m_player[1].m_bullet[j].m_active = FALSE;
}
}
}
// process enemys
for( i = 0; i < m_nMaxEnemys; i ++ )
{
if( !m_bEnemyLocked && !m_enemy[i].m_bBoring &&
m_enemy[i].m_active )
{
x = m_enemy[i].m_x;
y = m_enemy[i].m_y;
dir = m_enemy[i].m_dir;
if( rand() % 200 == 0 ||
!m_enemy[i].Move() )
{
m_enemy[i].ChangeDirection();
}
surface = m_plane.GetSurface( m_enemy[i] );
if( surface == OBJ_BRICK )
{
if( rand() % 100 < 30 )
{
m_enemy[i].ChangeDirection();
surface = m_plane.GetSurface( m_enemy[i] );
}
else
m_enemy[i].Fire();
}
else if( surface == OBJ_CONCRETE ||
surface == OBJ_RIVER )
{
m_enemy[i].ChangeDirection();
surface = m_plane.GetSurface( m_enemy[i] );
}
if( m_enemy[i].HitTest( m_player[0], (int)x, (int)y ) ||
m_enemy[i].HitTest( m_player[1], (int)x, (int)y ) )
{
m_enemy[i].m_x = x;
m_enemy[i].m_y = y;
m_enemy[i].m_dir = dir;
m_enemy[i].Fire();
}
else if( surface != OBJ_NULL && surface != OBJ_TREE )
{
m_enemy[i].m_x = x;
m_enemy[i].m_y = y;
m_enemy[i].m_dir = dir;
}
for( int j = 0; j < m_nMaxEnemys; j ++ )
{
if( i != j &&
m_enemy[i].HitTest( m_enemy[j], (int)x, (int)y ) )
{
// two enemys hit each other
m_enemy[i].ChangeDirection();
if( m_enemy[i].HitTest( m_enemy[j], (int)x, (int)y ) )
{
m_enemy[i].m_x = x;
m_enemy[i].m_y = y;
m_enemy[i].m_dir = dir;
}
break;
}
}
// the enemy can also eat the bonus
if( m_enemy[i].HitTest( m_bonus ) )
EatBonus( m_enemy[i] );
if( rand() % 100 == 0 )
m_enemy[i].Fire();
}
bullet = &m_enemy[i].m_bullet[0];
if( bullet->m_active )
{
if( !bullet->Move() )
bullet->m_active = FALSE;
surface = m_plane.HitSurface( *bullet );
if( surface == OBJ_BRICK ||
surface == OBJ_CONCRETE )
{
bullet->m_active = FALSE;
Explode( *bullet );
}
else if( surface == OBJ_HAWK )
{
bullet->m_active = FALSE;
Explode( *bullet, TRUE );
m_DirectSound.Play( EFFECT_EXPLODE );
m_gameState = GS_OVER;
}
for( k = 0; k < 2; k ++ )
{
if( bullet->HitTest( m_player[k] ) )
{
// enemy's bullet hit us
bullet->m_active = FALSE;
if( !m_player[k].m_bShield )
{
Explode( *bullet );
PlayerBeenHit( m_player[k] );
m_DirectSound.Play( EFFECT_EXPLODE );
}
}
}
}
}
// produce some enemys...
static DWORD lastTime;
DWORD thisTime = timeGetTime();
if( thisTime - lastTime > 3000 )
{
lastTime = thisTime;
BoreEnemy();
}
// It's time to unlock the enemys
if( m_bEnemyLocked &&
thisTime - m_lockTime > 10000 )
{
m_bEnemyLocked = FALSE;
}
if( m_nEnemys <= 0 && m_gameState == GS_ACTIVE )
{
m_gameState = GS_WIN;
m_lastTime = timeGetTime();
}
if( !m_player[0].m_active && !m_player[1].m_active )
m_gameState = GS_OVER;
}
void CGame::DrawWorld()
{
RECT rc;
rc.left = OFFSETX;
rc.right = rc.left + 416;
rc.top = OFFSETY;
rc.bottom = rc.top + 416;
DDClear( &rc, 0x0 );
rc.left = 0;
rc.right = SCREEN_W;
rc.top = 0;
rc.bottom = OFFSETY;
DDClear( &rc, m_dwFillColor );
rc.top = OFFSETY + 416;
rc.bottom = SCREEN_H;
DDClear( &rc, m_dwFillColor );
rc.left = 0;
rc.right = OFFSETX;
rc.top = OFFSETY;
rc.bottom = rc.top + 416;
DDClear( &rc, m_dwFillColor );
rc.left = OFFSETX + 416;
rc.right = SCREEN_W;
DDClear( &rc, m_dwFillColor );
m_plane.Draw( m_pddsBackBuffer );
for( int i = 0; i < m_nMaxEnemys; i ++ )
m_enemy[i].Draw( m_pddsBackBuffer );
m_player[0].Draw( m_pddsBackBuffer );
m_player[1].Draw( m_pddsBackBuffer );
m_plane.DrawTree( m_pddsBackBuffer );
for( i = 0; i < NUM_EXPLODES; i ++ )
m_explode[i].Draw( m_pddsBackBuffer );
m_bonus.Draw( m_pddsBackBuffer );
rc.left = 0;
rc.top = 0;
rc.right = 14;
rc.bottom = 14;
for( i = 0; i < m_nEnemysLeft; i ++ )
{
int x = 550 + i % 2 * 15;
int y = 68 + i / 2 * 15;
m_pddsBackBuffer->BltFast( x, y, m_pBmpList[8], &rc,
DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
}
rc.left = 28;
rc.right = rc.left + 28;
m_pddsBackBuffer->BltFast( 550, 300, m_pBmpList[8], &rc,
DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
m_pddsBackBuffer->BltFast( 20, 20, m_pBmpList[8], &rc,
DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
BltNumber( 70, 20, m_player[0].m_nScore );
rc.left = 14;
rc.right = rc.left + 14;
m_pddsBackBuffer->BltFast( 550, 317, m_pBmpList[8], &rc,
DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
BltNumber( 570, 317, m_player[0].m_nLife );
if( !m_bSingle )
{
rc.left = 56;
rc.right = rc.left + 28;
m_pddsBackBuffer->BltFast( 550, 350, m_pBmpList[8],
&rc, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
m_pddsBackBuffer->BltFast( 480, 20, m_pBmpList[8], &rc,
DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
BltNumber( 530, 20, m_player[1].m_nScore );
rc.left = 14;
rc.right = rc.left + 14;
m_pddsBackBuffer->BltFast( 550, 367, m_pBmpList[8],
&rc, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
BltNumber( 570, 367, m_player[1].m_nLife );
}
// draw level No.
m_pddsBackBuffer->BltFast( 550, 400, m_pBmpList[12], NULL,
DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
BltNumber( 580, 420, m_nLevel );
}
void CGame::BltNumber( int x, int y, int n )
{
char szNum[20];
sprintf( szNum, "%d", n );
int len = lstrlen( szNum );
for( int i = 0; i < len; i ++ )
{
RECT rc;
rc.left = (szNum[i] - '0') * 14;
rc.right = rc.left + 14;
rc.top = 0;
rc.bottom = 14;
m_pddsBackBuffer->BltFast( x, y, m_pBmpList[13], &rc,
DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
x += 15;
}
}
void CGame::DoSplash()
{
HRESULT hr;
DDClear( NULL, 0 );
hr = m_pddsBackBuffer->BltFast( 135, 130, m_pBmpList[10], NULL,
DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
if( hr == DDERR_SURFACELOST )
RestoreSurfaces();
RECT rc;
rc.left = 0;
rc.right = 28;
rc.top = 28;
rc.bottom = 56;
m_pddsBackBuffer->BltFast( 200, 300 + 30*(!m_bSingle),
m_pBmpList[1], &rc, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -