www.gusucode.com > VC++游戏雷霆战机源代码-源码程序 > VC++游戏雷霆战机源代码-源码程序\code\Game.cpp

    //Download by http://www.NewXing.com
// Game.cpp: implementation of the CGame class.
//
//////////////////////////////////////////////////////////////////////

#include "Game.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CGame::CGame(CDirectWnd* win)
{
	m_win = win;
	m_menu = new CMenu(m_win);
	m_bkground = new CBkGround(m_win);
	m_about = new CAbout(m_win);
	gamestate = game_menu;
}

CGame::~CGame()
{
	ReleaseAll();
}

void CGame::Run()
{				
	switch(gamestate)
	{
		case game_menu:	//游戏菜单
			{ 
				ShowMenu();
			}
			 break;
		case game_main:	//游戏主循环
			{
				GameLoop();      //游戏主循环 if Game_main
			}
			 break;

		case game_quit:
			{
				PostMessage(m_win->GetHwnd(),WM_QUIT,0,0);
			}
			 break;

		case game_over:
			{
				ShowGameOver();
			}
			 break;

		case game_about:
			{
				ShowAbout();
			}
			break;
	}

	if(DDERR_SURFACELOST == m_win->FlipScreen())
	{
		m_win->LoadBitmapResource();
	}
}

void CGame::ShowMenu()
{		
	int choseItem = m_menu->Run();
	if (KEYDOWN(VK_RETURN))
	{
		switch(choseItem)
		{
		case 1:
			{
				InitGame();
				m_win->m_music->Stop();
				m_win->m_music->Play(1);
				gamestate = game_main;
			}
			break;
		case 2:
			{
				gamestate = game_about;
			}
			break;
		case 3:
			gamestate = game_quit;
			break;
		}
	}
}

void CGame::GameLoop()
{
	if (KEYDOWN(VK_ESCAPE))
	{
		m_win->m_music->Stop();
		m_win->m_music->Play(0);
		ReleaseObList();
		gamestate = game_menu;
		return;
	}

	// 显示背景
	m_bkground->Run();

	// 显示关卡
	m_win->ShowText(SrcWidth/2-50,20,"第");
	m_win->ShowText(SrcWidth/2-30,20,missionNum);
	m_win->ShowText(SrcWidth/2-20,20,"关");

	// 显示分数
	m_win->ShowText(SrcWidth/2+70,20,"分数:");
	m_win->ShowText(SrcWidth/2+110,20,score);

	if(missionFinish)
	{
		if( missionNum < 5 )
		{
			m_win->ShowText(SrcWidth/2-100,SrcHeight/2-20,"第");
			m_win->ShowText(SrcWidth/2-80,SrcHeight/2-20,missionNum);
			m_win->ShowText(SrcWidth/2-70,SrcHeight/2-20,"关结束,请按空格键继续!");
			if( KEYDOWN(VK_SPACE) )
			{
				missionNum++;
				enemyNum = 0;
				missionFinish = FALSE;
			}
		}
		else if( 5 == missionNum )
		{
			m_win->ShowText(SrcWidth/2-100,SrcHeight/2-20,"恭喜你,你已经通关了,请按空格键退出!");
			if( KEYDOWN(VK_SPACE) )
			{
				m_win->m_music->Stop();
				m_win->m_music->Play(0);				
				ReleaseObList();
				gamestate = game_menu;
				return;
			}
		}
	}

	// 创建敌人
	if(!missionFinish) 
	{
		CreateEnemy();
	}

	// 遍历链表
	CObNode *p = m_ObList->Head->Next;
	while(p != m_ObList->Tail)
	{					
		CObNode *q = p->Next;
		while(q != m_ObList->Tail)
		{			
			if(NULL != q)
			{
				if(q->BaseObj->getExist())
					CheckHit(p,q);
				q = q->Next;		
			}
		}
		
		if(NULL != p->BaseObj)
		{
			p->BaseObj->Run();

			if ( 0 == p->BaseObj->getId() )
			{
				CPlayerPlane *pPlane = (CPlayerPlane *)(p->BaseObj);
				// 奖励生命
				if(score - oldscore >= 5000) 
				{ 
					oldscore = score;
					pPlane->setLifeNum(pPlane->getLifeNum() + 1);
					m_win->m_snd->PlaySound(7,0);
				}
				// 检测我机状态 
				if( 0 == pPlane->getLifeNum() && 0 == pPlane->getExist() )
				{	
					ReleaseObList();
					gamestate = game_over;
					return;
				}
			}

			// 检测敌机状态
			if ( 2 == p->BaseObj->getId() )
			{
				CEnemyPlane *ePlane = (CEnemyPlane *)(p->BaseObj);
				if( 1 == ePlane->getDead() )
				{
					score = score + ePlane->getScore();
				}
				if( 3 == ePlane->getEnemyType() )
				{
					if ( 1 == ePlane->getDead() )
						missionFinish = TRUE ;
				}
			}

			// 检测炸弹状态
			if ( 5 == p->BaseObj->getId() )
			{
				CBomb *bom = (CBomb *)(p->BaseObj);
				if( 0 == bom->getExist() )
					KillAllEnemy();
			}

			// 若对象存在标志为0,则删除该对象
			if(p->BaseObj->getExist() == 0)
			{
				p = p->Last;
				delete p->Next->BaseObj;
				m_ObList->Delete(p->Next);

			}

			p = p->Next;
		}
	}

}

void CGame::InitGame()
{
	srand( (unsigned)time( NULL ) );
	enemyNum = 0;
	score = 0;
	oldscore = score;
	missionNum = 1;
	missionFinish = FALSE;
	m_ObList = new CObList();
	new CPlayerPlane(m_win,m_ObList,3);

	char temp[5][100] = { 
		{ 
		  1,1,2,1,3,2,1,1,1,2,  1,2,1,1,3,1,2,1,3,2,
		  1,2,1,1,3,1,1,3,1,2,  1,2,1,1,3,1,2,1,3,1,
		  2,1,1,3,1,2,1,3,1,2,  1,2,2,1,3,1,2,1,3,1,
		  1,2,1,1,3,2,1,1,1,2,  1,2,2,1,3,1,2,1,3,1,
		  1,3,1,1,3,2,1,2,1,2,  1,2,2,1,3,1,2,1,3,4
		} ,
		{
		  2,1,3,1,3,2,1,2,1,2,  1,2,2,1,3,1,2,1,3,2,
		  1,3,1,3,2,2,1,3,1,2,  1,2,2,1,3,1,2,1,3,1,
		  2,1,3,1,3,2,1,2,1,2,  1,2,2,1,3,1,2,1,3,2,
		  1,3,1,3,2,2,1,3,1,2,  1,2,2,1,3,1,2,1,3,1,
		  2,1,3,1,3,2,1,2,1,2,  1,2,2,1,3,1,2,1,3,4
		},
		{
		  2,1,3,1,3,2,1,2,1,2,  1,2,2,1,3,1,2,1,3,2,
		  1,3,1,3,2,2,1,3,1,2,  1,2,2,1,3,1,2,1,3,1,
		  2,1,3,1,3,2,1,2,1,2,  1,2,2,1,3,1,2,1,3,2,
		  1,3,1,3,2,2,1,3,1,2,  1,2,2,1,3,1,2,1,3,1,
		  2,1,3,1,3,2,1,2,1,2,  1,2,2,1,3,1,2,1,3,4
		},
		{
		  2,1,3,1,3,2,1,2,1,2,  1,2,2,1,3,1,2,1,3,2,
		  1,3,1,3,2,2,1,3,1,2,  1,2,2,1,3,1,2,1,3,1,
		  2,1,3,1,3,2,1,2,1,2,  1,2,2,1,3,1,2,1,3,2,
		  1,3,1,3,2,2,1,3,1,2,  1,2,2,1,3,1,2,1,3,1,
		  2,1,3,1,3,2,1,2,1,2,  1,2,2,1,3,1,2,1,3,4
		},
		{
		  1,2,3,1,3,2,1,3,3,2,  1,2,2,1,3,1,2,1,3,2,
		  2,2,3,1,3,2,1,3,3,2,  1,2,2,1,3,1,2,1,3,1,
		  3,2,3,1,3,2,1,3,3,2,  1,2,2,1,3,1,2,1,3,1,
		  2,2,3,2,3,2,1,3,3,2,  1,2,2,1,3,1,2,1,3,1,
		  1,2,3,1,3,2,1,3,3,2,  1,2,2,1,3,1,2,1,3,4
		 }
				   	};
	for(int i=0;i<5;i++)
		for(int j=0;j<100;j++)
			mission[i][j]=temp[i][j];
}

void CGame::CheckHit(CObNode *Obj1,CObNode *Obj2)
{
	RECT r1,r2;

	m_win->GetRect(&r1,
				   Obj1->BaseObj->getPosX(),
				   Obj1->BaseObj->getPosY(),
				   Obj1->BaseObj->getWidth(),
				   Obj1->BaseObj->getHeight()
				   );
	m_win->GetRect(&r2,
				   Obj2->BaseObj->getPosX(),
				   Obj2->BaseObj->getPosY(),
				   Obj2->BaseObj->getWidth(),
				   Obj2->BaseObj->getHeight()
				   );
	// 0:我机 1:我机子弹 2: 敌机 3:敌机子弹 4:奖励物品 
	switch(Obj1->BaseObj->getId())
	{
		case 0:
			{
				if(2 == Obj2->BaseObj->getId())
				{
					CPlayerPlane *pPlane = (CPlayerPlane *)(Obj1->BaseObj);
					CEnemyPlane *ePlane = (CEnemyPlane *)(Obj2->BaseObj);
					if( !pPlane->getSuper() )
					{
						if( IsCollide(&r1,&r2) )
						{
							pPlane->setLife(pPlane->getLife() - ePlane->getLife());
						}
					}
				}
				else if(3 == Obj2->BaseObj->getId())
				{
					CPlayerPlane *pPlane = (CPlayerPlane *)(Obj1->BaseObj);
					CEnemyBullet *eBullet = (CEnemyBullet *)(Obj2->BaseObj);
					if( !pPlane->getSuper() )
					{
						if( IsCollide(&r1,&r2) )
						{
							pPlane->setLife(pPlane->getLife() - eBullet->getPower());
						}
					}
				}
				else if(4 == Obj2->BaseObj->getId())
				{
					if( IsCollide(&r1,&r2) )
					{
						Obj2->BaseObj->setExist(0);
						CPlayerPlane *pPlane = (CPlayerPlane *)(Obj1->BaseObj);
						CBonus *bonus = (CBonus *)(Obj2->BaseObj);
						pPlane->getBonus(bonus->getBonusType());
						m_win->m_snd->PlaySound(4,0);
						score = score + 100;
					}
				}
			}
			break;
		case 1:
			{
				if(2 == Obj2->BaseObj->getId())
				{
					if( IsCollide(&r1,&r2) )
					{
						Obj1->BaseObj->setExist(0);
						CPlayerBullet *pBullet = (CPlayerBullet *)(Obj1->BaseObj);
						CEnemyPlane *ePlane = (CEnemyPlane *)(Obj2->BaseObj);
						new CExplode(m_win,
									 m_ObList,
									 ePlane->getPosX(),
									 ePlane->getPosY(),
									 2);
						m_win->m_snd->PlaySound(5,0);
						ePlane->setLife(ePlane->getLife() - pBullet->getPower());
					}
				}
			}
			break;
		case 2:
			{
				if(1 == Obj2->BaseObj->getId())
				{
					if( IsCollide(&r1,&r2) )
					{
						Obj2->BaseObj->setExist(0);						
						CEnemyPlane *ePlane = (CEnemyPlane *)(Obj1->BaseObj);
						CPlayerBullet *pBullet = (CPlayerBullet *)(Obj2->BaseObj);
						new CExplode(m_win,
									 m_ObList,
									 ePlane->getPosX(),
									 ePlane->getPosY(),
									 2);
						m_win->m_snd->PlaySound(5,0);
						ePlane->setLife(ePlane->getLife() - pBullet->getPower());
					}
				}
				else if(0 == Obj2->BaseObj->getId())
				{	
					CEnemyPlane *ePlane = (CEnemyPlane *)(Obj1->BaseObj);
					CPlayerPlane *pPlane = (CPlayerPlane *)(Obj2->BaseObj);	
					if ( !pPlane->getSuper() )
					{
						if( IsCollide(&r1,&r2) )
						{				   					
							pPlane->setLife(pPlane->getLife() - ePlane->getLife());					
			
						}
					}
				}
			}
			break;
		case 3:
			{
				if(0 == Obj2->BaseObj->getId())
				{
					CEnemyBullet *eBullet = (CEnemyBullet *)(Obj1->BaseObj);
					CPlayerPlane *pPlane = (CPlayerPlane *)(Obj2->BaseObj);
					if ( !pPlane->getSuper() )
					{
						if( IsCollide(&r1,&r2) )
						{
							Obj1->BaseObj->setExist(0);						
							pPlane->setLife(pPlane->getLife() - eBullet->getPower());						
						}
					}
				}
			}
			break;
		case 4:
			{
				if(0 == Obj2->BaseObj->getId())
				{
					if( IsCollide(&r1,&r2) )
					{
						Obj1->BaseObj->setExist(0);						
						CBonus *bonus = (CBonus*)(Obj1->BaseObj);
						CPlayerPlane *pPlane = (CPlayerPlane*)(Obj2->BaseObj);						
						pPlane->getBonus(bonus->getBonusType());
						m_win->m_snd->PlaySound(4,0);
						score = score + 100;
					}
				}
			}
	}
}

BOOL CGame::IsCollide(RECT *rt1,RECT *rt2)
{
	if( (rt1->top > rt2->top && rt1->top < rt2->bottom) ||
		(rt1->bottom > rt2->top && rt1->bottom < rt2->bottom) )
	{
		if( ( rt1->left > rt2->left && rt1->left < rt2->right) ||
			( rt1->right > rt2->left && rt1->right < rt2->right ) )
		{
			return TRUE;
		}
	}
	if( (rt2->top > rt1->top && rt2->top < rt1->bottom) ||
		(rt2->bottom > rt1->top && rt2->bottom < rt1->bottom) )
	{
		if( ( rt2->left > rt1->left && rt2->left < rt1->right) ||
			( rt2->right > rt1->left && rt2->right < rt1->right ) )
		{
			return TRUE;
		}
	}
	return FALSE;
}

void CGame::ReleaseAll()
{
	SAFE_DELETE(m_menu)
	SAFE_DELETE(m_bkground)
	SAFE_DELETE(m_about)
	ReleaseObList();
}

void CGame::ReleaseObList()
{
	CObNode *p = m_ObList->Head->Next;
	while(p != m_ObList->Tail)
	{
		CObNode *Next;
		Next = p->Next;
		delete p->BaseObj;
		delete p;
		p = Next;
	}
	m_ObList->Count = 0;
	m_ObList->Head->Next = m_ObList->Tail;
	m_ObList->Tail->Last = m_ObList->Head;

	SAFE_DELETE(m_ObList)
}

void CGame::CreateEnemy()
{
	static int cetime = timeGetTime();
	int posx,speedx,speedy;
	if (enemyNum < 100)
	{
		if (timeGetTime()-cetime>2000)
		{
			cetime = timeGetTime();
			switch(mission[missionNum-1][enemyNum])
			{
				
				case 1:
					{
						posx = abs(rand()%SrcWidth - 50);
						if( 5 == missionNum )
						{
							speedx = rand()%2;
							if(posx > SrcWidth/2)
								speedx = -abs(speedx);
						}
						else
						{
							speedx = 0;
						}
						new CEnemyPlane(m_win,
										m_ObList,
										posx,
										0,
										speedx,
										2,
										0,
										5+3*(missionNum-1));
					}
					break;
				case 2:
					{
						posx = abs(rand()%SrcWidth - 50);
						speedx = rand()%2;
						if(posx > SrcWidth/2)
							speedx = -abs(speedx);
						if ( 0 == speedx ) 
							speedy = 2;
						else
							speedy = rand()%2 + 1;
						new CEnemyPlane(m_win,
										m_ObList,
										posx,
										0,
										speedx,
										speedy,
										1,
										5+3*(missionNum-1));
					}
					break;
				case 3:
					{
						posx = abs(rand()%SrcWidth - 66);
						speedx = rand()%2;
						if(posx > SrcWidth/2)
							speedx = -abs(speedx);
						if ( 0 == speedx ) 
							speedy = 2;
						else
							speedy = rand()%2 + 1;
						new CEnemyPlane(m_win,
										m_ObList,
										posx,
										0,
										speedx,
										speedy,
										2,
										10+5*(missionNum-1));
					}
					break;
				case 4:
					{
						posx = abs(rand()%SrcWidth - 114);
						new CEnemyPlane(m_win,
										m_ObList,
										posx,
										100,
										1,
										0,
										3,
										500+200*(missionNum-1));
					}
					break;
			}
			enemyNum++;
		}
	}
}

void CGame::ShowGameOver()
{
	m_win->BltBitMap(m_win->lpBKGObject[10]);
	if (KEYDOWN(VK_ESCAPE))
	{
		m_win->m_music->Stop();
		m_win->m_music->Play(0);
		gamestate = game_menu;
	}
}

void CGame::KillAllEnemy()
{
	// 2: 敌机 3:敌机子弹
	CObNode *p = m_ObList->Head->Next;
	while(p != m_ObList->Tail)
	{
		if( 2 == p->BaseObj->getId() )
		{
			CEnemyPlane *ePlane = (CEnemyPlane *)(p->BaseObj);
			ePlane->setLife(ePlane->getLife() - 50);
		}
		else if( 3 == p->BaseObj->getId() )
		{
			p = p->Last ;
			delete p->Next->BaseObj;
			m_ObList->Delete(p->Next);
		}
		p = p->Next;
	}
}

void CGame::ShowAbout()
{
	m_about->Run();
	if (KEYDOWN(VK_ESCAPE))
	{
		gamestate = game_menu;
	}
}