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

📄 game.cpp

📁 VC环境下运行的坦克大战
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		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" );
	DDReLoadBitmap( m_pBmpList[4], "graphics\\explode2.bmp" );
	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 );
}



void CGame::UpdateFrame()
{
	static DWORD lastTick = timeGetTime();

⌨️ 快捷键说明

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