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

📄 game.cpp

📁 坦克大战
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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], "Tile" );
	DDReLoadBitmap( m_pBmpList[1], "Player1" );
	DDReLoadBitmap( m_pBmpList[2], "Bullet" );
	DDReLoadBitmap( m_pBmpList[3], "Explode1" );
	DDReLoadBitmap( m_pBmpList[4], "Explode2" );
	DDReLoadBitmap( m_pBmpList[5], "Enemys" );
	DDReLoadBitmap( m_pBmpList[6], "Bonus" );
	DDReLoadBitmap( m_pBmpList[7], "Bore" );
	DDReLoadBitmap( m_pBmpList[8], "Misc" );
	DDReLoadBitmap( m_pBmpList[9], "Player2" );
	DDReLoadBitmap( m_pBmpList[10], "Splash" );
	DDReLoadBitmap( m_pBmpList[11], "GameOver" );
	//12
	//13
	DDReLoadBitmap( m_pBmpList[14], "Shield" );
	DDReLoadBitmap( m_pBmpList[15], "About" );
	DDReLoadBitmap( m_pBmpList[16], "Logo" );

}


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;//save old pos and dir
		y = m_player[k].m_y;
		dir = m_player[k].m_dir;

		surface = m_plane.GetSurface( m_player[k] );
		if(surface==OBJ_ICE) //reduce speed of player that is on ice
			m_player[k].m_speed=0.8f;
		else
			m_player[k].m_speed=2.8f;

		if( !m_player[k].m_bBoring && m_gameState != GS_OVER )
		{
			if( m_player[k].ProcessInput(input[k], time) )//refresh new pos and dir via this func
				m_DirectSound.Play( EFFECT_FIRE );
		}
		surface = m_plane.GetSurface( m_player[k] );
		if( surface != OBJ_NULL &&
			surface != OBJ_TREE && surface!=OBJ_ICE)
		{
			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 < 3; 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>=2 );
			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_
				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 )
					{
						
						m_enemy[i].m_level=m_enemy[i].m_level-m_player[k].m_type-1;
						if( m_enemy[i].m_level < 0 )
							m_enemy[i].m_active = FALSE;
						else
							m_DirectSound.Play( EFFECT_HIT );
					}
					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) * 10; //rewards score
					}
					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;
			float oldspeed=m_enemy[i].m_speed;

			surface=m_plane.GetSurface(m_enemy[i]);
			if(surface==OBJ_ICE)
				m_enemy[i].m_speed=0.8f;
			else
				m_enemy[i].m_speed=oldspeed;
			
			if( rand() % 200 == 0 ||
				!m_enemy[i].Move() )
			{
				m_enemy[i].ChangeDirection();
			}
			m_enemy[i].m_speed=oldspeed;  //restore speed for next effect
			
			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 && surface!=OBJ_ICE)
			{
				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( random(0,10-m_nLevel/4) == 2 )
				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,m_enemy[i].m_type>3 );
			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 )
					{
						if(--(m_player[k].m_nArmor)<0)
						{
							Explode( *bullet );
							PlayerBeenHit( m_player[k] );
							m_DirectSound.Play( EFFECT_EXPLODE );
						}
						else
							m_DirectSound.Play( EFFECT_HIT );
					}
				}
			}
		}
	}

	// 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;

	DrawGround();
	rc.left = 608;
	rc.right = 640;
	rc.top = 0;
	rc.bottom = 480;
	DDClear( &rc, 0 );
	
	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 );
	
	char num[5];
	
	sprintf(num,"%d",m_nEnemysLeft);
	OutputText(610,50,num);

	rc.left=0;
	rc.right=32;
	rc.top=0;
	rc.bottom=32;
	m_pddsBackBuffer->BltFast( 608, 10, m_pBmpList[8], &rc,
			DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
	
	rc.left = 32;
	rc.right = rc.left + 32;
	m_pddsBackBuffer->BltFast( 608, 200, m_pBmpList[8], &rc,
			DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );

	sprintf(num,"%d",m_player[0].m_nLife);
	OutputText(610,240,num);
	
	sprintf(num,"%d",m_player[0].m_nScore);
	OutputText( 608, 255, num);

	/*m_pddsBackBuffer->BltFast( 20, 20, m_pBmpList[8], &rc,
			DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
	

	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 = 64;
		rc.right = 64+32;
		m_pddsBackBuffer->BltFast( 608, 300, m_pBmpList[8],
			&rc, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
	
		sprintf(num,"%d",m_player[1].m_nLife);
		OutputText(610,340,num);
	
		sprintf(num,"%d",m_player[1].m_nScore);
		OutputText( 608, 355, num);
	}

	// draw level No.
	rc.left=96;
	rc.right=128;
	m_pddsBackBuffer->BltFast( 608, 410, m_pBmpList[8], &rc,
			DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
	sprintf(num,"%d", m_nLevel ); 
	OutputText(610,450,num);
}


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 = 32;
	rc.top = 32;
	rc.bottom = 64;
	m_pddsBackBuffer->BltFast( 200, 300 + 30*m_iSel,
		m_pBmpList[1], &rc, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
	OutputText(550,450,"V 0.11 Siney");
}



void CGame::UpdateFrame()
{
	static DWORD lastTick;
	static float fps;
	if(timeGetTime()-lastTick<20)
		return;
	lastTick = timeGetTime();

	if( m_gameState == GS_OVER || m_gameState == GS_ACTIVE ||
		m_gameState == GS_WIN )
		ProcessInput();	//process input

	switch( m_gameState )
	{
	case GS_SPLASH:
		DoSplash();
		break;
	
	case GS_OVER:
		DrawWorld();
		m_pddsBackBuffer->BltFast( 200, 200, m_pBmpList[11],
			NULL, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
		break;

	case GS_ACTIVE:
		DrawWorld();
		break;
		
	case GS_WIN:
		DrawWorld();
		
		if( timeGetTime() - m_lastTime > 3000 ||
			timeGetTime() < m_lastTime )
		{
			m_gameState = GS_ACTIVE;
			m_nLevel ++;
			InitLevel();
		}
		break;
	case GS_ABOUT:
		DoAbout();
		break;
	case GS_BEGIN:
		DoBegin();
		break;
	}

⌨️ 快捷键说明

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