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

📄 game.cpp

📁 一款不错的飞机模拟游戏
💻 CPP
📖 第 1 页 / 共 3 页
字号:

}
//------------------------------------------------------------------------------
//场景更换
void CGame::UpdateFrame()
{
	//如果游戏结束
	if ( 0==m_iGameStatus || 
		2==m_iGameStatus )
	{
		DrawScore();
		return;	
	}

	#if _WIN32_WCE
	Fire();
	#else
	if(FALSE == m_iniAutoFire)
	{
		if(GetAsyncKeyState(m_iniFire))
			Fire();
	}
	else
		Fire();
	#endif
	
	//放雷
	if(GetAsyncKeyState(m_iniThunder))	
		FlashScreen();

	DrawMap();
	Check();
	CheckBoss();
	DrawPlane();
	DrawBall();
	DrawFoe();
	DrawBlast();
	DrawFoeBoss();
	DrawScore();

	DrawFlip();

}
//------------------------------------------------------------------------------
//将缓冲内容贴到屏幕
void CGame::DrawFlip()
{
	RECT Window;
	POINT pt;
	GetClientRect(hWnd, &Window);
	pt.x=pt.y=0;
	ClientToScreen(hWnd, &pt);
	OffsetRect(&Window, pt.x, pt.y);

	HDC hDC = GetDC(hWnd);
	BitBlt(hDC,0,0,ScreenW,ScreenH,g_hBufDC,0,0,SRCCOPY);
	ReleaseDC(hWnd,hDC);
	hDC = NULL;

	return ;
}
//------------------------------------------------------------------------------
//画我机子弹
void CGame::DrawBall()
{
	for (int i=0; i<BALLNUM; i++)
	{
		RECT rcL,rcR;
		rcL.left	= BallPosL[i].x;
		rcL.top		= BallPosL[i].y;
		rcL.right	= rcL.left + 10;
		rcL.bottom	= rcL.top + 20;
		rcR.left	= BallPosR[i].x;
		rcR.top		= BallPosR[i].y;
		rcR.right	= rcR.left + 10;
		rcR.bottom	= rcR.top + 20;

		BitBlt(g_hBufDC,rcL.left,rcL.top,ScreenW,ScreenH,g_hBalDC[0],0,0,SRCINVERT);
		BitBlt(g_hBufDC,rcR.left,rcR.top,ScreenW,ScreenH,g_hBalDC[1],0,0,SRCINVERT);
		
		BallPosL[i].x --;
		BallPosL[i].y -= 26;
		BallPosR[i].x ++;
		BallPosR[i].y -= 26;

	}
}
//------------------------------------------------------------------------------
//画敌机
void CGame::DrawFoe()
{
	RECT rect;

	for(int i=0; i<FOENUM; i++)
	{
		if( FoePos[i].x<=0 || FoePos[i].x>=ScreenW || 
			FoePos[i].y<=0 || FoePos[i].y>=ScreenH )
		{
			FoeDead[i] = 0;
		}

		if (0 != FoeDead[i])	//敌机未毁
		{
			switch (FoeType[i])
			{
			case 0://敌机2
				GetRect( &rect, FoePos[i].x, FoePos[i].y, 50, 57);
				BitBlt(g_hBufDC,rect.left-10 ,rect.top-10,ScreenW,ScreenH,
					g_hFoePlaDC[1],0,0,SRCINVERT);
				
				FoePos[i].y+=FoeSpeed[i]+(movespeed);
				FoePos[i].x+=FoeWay[i];		
			
				break;

			case 1://子弹1
				GetRect( &rect, FoePos[i].x, FoePos[i].y, 8, 8);
				BitBlt(g_hBufDC,rect.left,rect.top,ScreenW,ScreenH,
					g_hFoeBalDC[0],0,0,SRCINVERT);
	
				FoePos[i].y+=FoeSpeed[i]+(movespeed+2);
				FoePos[i].x+=FoeWay[i];

				break;

			case 2://敌机1(自杀型)
				GetRect( &rect, FoePos[i].x, FoePos[i].y, 35, 35);
				BitBlt(g_hBufDC,rect.left,rect.top,ScreenW,ScreenH,
					g_hFoePlaDC[0],0,0,SRCINVERT);
	
				FoePos[i].y+=FoeSpeed[i]+(movespeed+2);
				FoePos[i].x+=FoeWay[i];
	
				break;

			case 3://子弹2
				GetRect( &rect, FoePos[i].x, FoePos[i].y, 26, 28);
				BitBlt(g_hBufDC,rect.left-10,rect.top-10,ScreenW,ScreenH,
					g_hFoeBalDC[1],0,0,SRCINVERT);

				FoePos[i].y+=FoeSpeed[i]+(movespeed);
				FoePos[i].x+=FoeWay[i];
				break;

			}

		}

		if ( FoeDead[i]==0 )
		{
			FoePos[i].x=(int)(ScreenW*((long)rand()/32767.0))+50;
			FoePos[i].y=(int)(35*((long)rand()/32767.0));
			FoeSpeed[i]=(int)(4*((long)rand()/32767.0));
			FoeWay[i]=(int)(3*((long)rand()/32767.0))-1;//-1,0,1
			
			//敌机类型
			FoeType[i]=(int)(4*((long)rand()/32767.0));//0,1,2,3
			FoeDead[i]=1;	//敌人复活
		}
	}
}
//------------------------------------------------------------------------------
//画爆炸火焰效果
void CGame::DrawBlast()
{
	//敌机爆炸火焰
	for (int f=0; f<FOENUM; f++)
	{
		if (0 != FoeBlastType[f])
		{
			RECT rc,rc1;
			GetRect(&rc, FoeBlastPos[f].x, FoeBlastPos[f].y, 66, 66);
			GetRect(&rc1, (FoeBlastType[f] - 1)*66, 0, 66, 66);
	
			BitBlt(g_hBufDC,rc.left,rc.top,rc1.right-rc1.left,rc1.bottom-rc1.top,
				g_hFoeBusDC,rc1.left,rc1.top,SRCINVERT);
			
			static int otime[FOENUM];
			if (GetTickCount()-otime[f]>150)
			{
				otime[f]=GetTickCount();
				FoeBlastType[f]++;//更新火焰状态
				if (FoeBlastType[f]==9 ) FoeBlastType[f]=0;//火焰完毕
			}

		}
	}

	//我机爆炸火焰
	if (0 != BlastTpye)
	{
		RECT rect, srect;
		GetRect(&rect, BlastPos.x, BlastPos.y, 66, 66);
		GetRect(&srect,(BlastTpye-1)*66, 0, 66, 66);

		BitBlt(g_hBufDC,rect.left,rect.top,srect.right-srect.left,srect.bottom-srect.top,
				g_hBusDC,srect.left,srect.top,SRCINVERT);

		static int oldtime=0;//延时
		if (GetTickCount()-oldtime>200)
		{
			oldtime=GetTickCount();
			BlastTpye++;//更新火焰状态
			if (BlastTpye==9 ) BlastTpye=0;//火焰完毕
				
		}
			
	}
	
}
//------------------------------------------------------------------------------
//游戏检测
void CGame::Check()
{
	int b=0;
	//检测敌机是否被击落
	for (int e=0; e<FOENUM; e++)
	{
		//敌人已消灭
		if (0 == FoeDead[e]) 
			continue;
		
		switch (FoeType[e])
		{
		case 0:
		case 2://是敌机
			//敌机不在窗口内
			if (TRUE == IsOutRect(FoePos[e])) 
				continue;
			for (b=0; b<FOENUM; b++)
			{
				//检测左子弹
				if (FALSE == IsOutRect(BallPosL[b]))
				{
					if ( abs(FoePos[e].x-BallPosL[b].x+15)<15 && 
						abs(FoePos[e].y-BallPosL[b].y+11)<15 )
					{
						PlaySound(MAKEINTRESOURCE(IDR_WAVE_BOMB),g_hInst,SND_RESOURCE|SND_ASYNC);
						FoeDead[e] = 0;		//使敌机销毁
						BallPosL[b].y = 0;	//使子弹消失
						FoeBlastPos[e].x = FoePos[e].x - 10;	//火焰坐标
						FoeBlastPos[e].y = FoePos[e].y - 8;		//火焰坐标
						FoeBlastType[e] = 1;	//火焰状态
						
						//敌机损失数量++
						m_iFoeDead ++;
						m_iFoeTotalDead++;
						
					}
				}

				//检测右子弹
				if (FALSE == IsOutRect(BallPosR[b]))
				{
					if ( abs(FoePos[e].x-BallPosR[b].x+15)<15 && 
						abs(FoePos[e].y-BallPosR[b].y+11)<15 )
					{
						PlaySound(MAKEINTRESOURCE(IDR_WAVE_BOMB),g_hInst,SND_RESOURCE|SND_ASYNC);
						FoeDead[e] = 0;		//使敌机销毁
						BallPosR[b].y = 0;	//使子弹消失
						FoeBlastPos[e].x = FoePos[e].x - 10;	//火焰坐标
						FoeBlastPos[e].y = FoePos[e].y - 8;		//火焰坐标
						FoeBlastType[e] = 1;	//火焰状态
						
						//敌机损失数量++
						m_iFoeDead ++;
						m_iFoeTotalDead++;
						
					}
				}
				
			

			}
			break;

		case 1:
		case 3://是子弹
			break;
		}
				
	}
	
	
	//检测我机是否撞毁
	for (int p=0; p<FOENUM; p++)
	{
		//超级用户,打不死哈哈
		if(TRUE == m_iniSuperUser) break;

		//我机重新初始化的时候
		if(TRUE == m_bNewReset) break;

		if(FoeDead[p]==0) 
			continue;
		if(IsOutRect(FoePos[p])) 
			continue;
		
		switch (FoeType[p])
		{
		case 1:
		case 3:	//子弹
			if ( abs(pos.x-FoePos[p].x+21)<15 &&
				abs(pos.y-FoePos[p].y+26)<12 )
			{
				FoeDead[p]=0;
				BlastPos.x=FoePos[p].x-29;
				BlastPos.y=FoePos[p].y-29;
				BlastTpye = 1;
				//我机飞机数量--,被击中
				m_iReMain --;
				//损失总数++
				m_iTotalPlane++;
			}
			break;
		case 0:
		case 2:	//敌机
			if ( abs(pos.x-FoePos[p].x+7)<15 && 
				abs(pos.y-FoePos[p].y+12)<12 )
			{
				FoeDead[p]=0;
				BlastPos.x=FoePos[p].x-15;
				BlastPos.y=FoePos[p].y-15;
				BlastTpye = 1;
				//我机飞机数量--,被撞毁
				m_iReMain --;
				//损失总数++
				m_iTotalPlane++;
				
			}
			break;
		}
	}
	
	if (m_iReMain <= 0) //游戏结束
	{
		m_iGameStatus = 2;
		m_bResetGame = TRUE;
	}

}
//------------------------------------------------------------------------------
//检测我机是否被敌机BOSS击中
void CGame::CheckBoss()
{	
	//BOSS没有出现
	if(FALSE == m_bSeeBoss) return;
	
	int b;

	//BOSS是否被我机击中
	for(b=0;b<BALLNUM;b++)
	{
		if ( abs(m_pFoeBossPos.x-BallPosL[b].x)<10 && 
				abs(m_pFoeBossPos.y-BallPosL[b].y)<20 )
		{
			m_iFoeBossBlood--;
		}
	
		if ( abs(m_pFoeBossPos.x-BallPosR[b].x)<10 && 
			abs(m_pFoeBossPos.y-BallPosR[b].y)<20 )
		{
			m_iFoeBossBlood--;
		}

	}

	//超级用户,打不死哈哈
	if(TRUE == m_iniSuperUser) return;
	//我机重新初始化的时候
	if(TRUE == m_bNewReset) return;


	//我机是否被BOSS击中
	switch(m_iLevel)
	{
	case 1:	//第一关
	case 2:
	case 3:
	case 4:
	case 5:
		for (b=0; b<m_iBossTotalBalNum; b++)
		{
			if ( abs(pos.x-m_pFoeBossBalPos[b].x+12)<25 &&
				abs(pos.y-m_pFoeBossBalPos[b].y+12)<30)
			{
				BlastPos.x=m_pFoeBossBalPos[b].x-29;
				BlastPos.y=m_pFoeBossBalPos[b].y-29;
				BlastTpye = 1;
				//我机飞机数量--,被击中
				m_iReMain --;
				//损失总数++
				m_iTotalPlane++;

			}
		}
		//我机被BOSS撞毁,重叠半个飞机距离
		if ( abs(m_pFoeBossPos.x+50-pos.x)<25 && 
			abs(m_pFoeBossPos.y+60-pos.y)<30 )
		{
			BlastPos.x=pos.x-29;
			BlastPos.y=pos.y-29;
			BlastTpye = 1;
			//我机飞机数量--,被撞毁
			m_iReMain --;
			//损失总数++
			m_iTotalPlane++;

		}


		break;

	}


}
//------------------------------------------------------------------------------
//是否在区域内
BOOL CGame::IsOutRect(POINT p)
{
	if (p.x<35 || p.x>ScreenW+35 || p.y<35 || p.y>ScreenH+35)
		return TRUE;
	else
		return FALSE;
}
//------------------------------------------------------------------------------
//我机放雷
void CGame::FlashScreen()
{
	//一架飞机只有3次放雷的机会
	if(m_iBomb <= 0) return;

	TCHAR tcWaveFile[MAX_PATH]={'\0'};
	wcscpy(tcWaveFile,tcAppExePath);
	wcscat(tcWaveFile,TEXT("Q11\\thunder.WAV"));
	PlaySound (tcWaveFile,NULL,SND_FILENAME|SND_ASYNC);	
	HDC hDC = GetDC(hWnd);
	int iBombW = 84;	//雷的图片宽度
	for(int i=0;i<(ScreenW/iBombW)+1;i++)
		BitBlt(hDC,i*84,0,ScreenW,ScreenH,g_hBomDC,0,0,SRCINVERT);
	ReleaseDC(hWnd,hDC);
	hDC = NULL;
	
	//敌机消失,只是消失呢,不给计算敌机损失,
	//保护一下自己而已。想打通关,就用作弊方式吧
	for (i=0; i<FOENUM; i++)
		FoeDead[i] = 0;

	//如果有BOSS
	if(TRUE == m_bSeeBoss)
	{
		//如果BOSS与我机相距少于等于一个飞机宽AND
		//少于等于一个飞机高度,BOSS血减掉5
		//否则雷白放了哦:-)减少一点难度吧,呵呵
		m_iFoeBossBlood -= 5;

		for(i=0;i<m_iBossTotalBalNum;i++)
		{
			m_pFoeBossBalPos[i].x = ScreenW; 
			m_pFoeBossBalPos[i].y = ScreenH; 
		}
	}

	//雷数量--
	//超级用户当然不减了哈哈
	if(FALSE == m_iniSuperUser) 
		m_iBomb --;

	Sleep(500);

}
//------------------------------------------------------------------------------
//垂直方向开启屏幕效果
void CGame::VOpen()
{
	HDC hDC = GetDC(hWnd);

	RECT rc;
	GetWindowRect(hWnd,&rc);

	for (int m=0;m<121;m++)
	{
		BitBlt(hDC,0,rc.top,
			   ScreenW,(rc.bottom-rc.top),
			   g_hBufDC,0,rc.top,BLACKNESS);
		rc.top	  -= 2;
		rc.bottom += 2;
		::Sleep(5);
	}
	
	ReleaseDC(hWnd,hDC);
	hDC = NULL;
}
//------------------------------------------------------------------------------
//垂直方向关闭屏幕效果
void CGame::VClose()
{
	TCHAR tcWaveFile[MAX_PATH]={'\0'};
	wcscpy(tcWaveFile,tcAppExePath);
	wcscat(tcWaveFile,TEXT("Q11\\open.wav"));
	PlaySound (tcWaveFile,NULL,SND_FILENAME|SND_ASYNC);	

	HDC hDC = GetDC(hWnd);

	RECT rc;
	GetClientRect(hWnd,&rc);

	int a,b;
	#if _WIN32_WCE
	a = 121;
	b = 2;
	#else
	a = 30;
	b = 20;
	#endif

	for (int m=0;m<a;m++)
	{
		BitBlt(hDC,0,0,ScreenW,rc.top,g_hBufDC,0,0,BLACKNESS);
		BitBlt(hDC,0,rc.bottom,ScreenW,(ScreenH-rc.bottom),g_hBufDC,0,0,BLACKNESS);

		rc.top    += b;
		rc.bottom -= b;
	
		::Sleep(5);
	}
	
	//用于绘制“请稍候……”
	rc.left=0;
	rc.top=ScreenH/2;
	rc.right=ScreenW;
	rc.bottom=ScreenH;
	SetTextColor(hDC,0x0000ffff);//黄色
	SetBkMode(hDC,TRANSPARENT);//设置透明背景
	if(m_iLevel > 1)
	{
		TCHAR str[256] = {'\0'};
		swprintf(str,TEXT("祝贺通过第%d关!"),m_iLevel-1);
		DrawText(hDC,str,-1,&rc,DT_CENTER);
		rc.top += 20;
		rc.bottom += 20;
	}
	DrawText(hDC,TEXT("请稍侯……"),-1,&rc,DT_CENTER);

	ReleaseDC(hWnd,hDC);
	hDC = NULL;

	Sleep(1000);

}

//------------------------------------------------------------------------------
//平行方向打开屏幕效果
void CGame::LOpen()
{
	HDC hDC = GetDC(hWnd);

	RECT rc;
	GetWindowRect(hWnd,&rc);

	for (int m=0;m<121;m++)
	{
		BitBlt(hDC,rc.left,0,(rc.right-rc.left),
			   ScreenH,g_hBufDC,rc.left,0,SRCCOPY);
		rc.left  -= 1;
		rc.right += 1;
	}

	ReleaseDC(hWnd,hDC);
	hDC = NULL;
}
//------------------------------------------------------------------------------
//平行方向关闭屏幕效果
void CGame::LClose()
{
	TCHAR tcWaveFile[MAX_PATH]={'\0'};

⌨️ 快捷键说明

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