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

📄 fight.cpp

📁 一款C++小游戏的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	else 
		break;
	}
	
	return ;
}
//********************************************************&|*
//处理键盘输入
//***********************************************************
void GetInput(void)
{   
	int i=0;
	if(GetAsyncKeyState(VK_UP)){A11.direct=Aup;}
	if(GetAsyncKeyState(VK_RIGHT)){A11.direct=Aright;}
	if(GetAsyncKeyState(VK_DOWN)){A11.direct=Adown;}
	if(GetAsyncKeyState(VK_LEFT)){A11.direct=Aleft;}
	if(GetAsyncKeyState(VK_SPACE))
	{
		if(A11.bfire)return;
		A11.bfire=TRUE;
		while(!Afire[i].bdead){i++;}
		if(i<cenemy)
		{
			Afire[i].bdead=FALSE;
			Afire[i].direct=A11.direct;
			Afire[i].type=Fplane;
			Afire[i].x=A11.x+2*A11.width/6;
			Afire[i].y=A11.y+2*A11.height/6;
		}
	}
	return;
}
//**********************************************************
//checkhit()处理碰撞
//**********************************************************
void CheckHit()
{
	//注意:
	//1.在进行碰撞的检查时,检查的距离必须小于赋值的条件检测的距离。
	//2.注意区别:碰撞检测距离、赋值检测距离、于距离合法性的赋值距离
	//即:a.(if(A11.x<100||A11.x>640||A11.y<5||A11.y>530)
	//    b.if(A11.y<10  ){Aflame[i].x=A11.x;Aflame[i].y=A11.y;} 
	//    c.if(Aflame[i].x<100){Aflame[i].x=100;}
	//中的三个检测距离的作用和大小的顺序必须符合的条件。
	//否则将产生不可预测的结果。
	RECT drect,srect;
	int i=0;
	//1.下次考虑一下飞机碰撞后的时间延迟(闪烁)
    //2.碰撞的精确位置
	if(!A11.bdead)
	{
		if(A11.x<100||A11.x>640||A11.y<3||A11.y>535)
		{
			while(!Aflame[i].bdead){i++;}

			if(i<cenemy)
			{
				if(A11.y<5  ){Aflame[i].x=A11.x;Aflame[i].y=A11.y;}
				if(A11.y>535){Aflame[i].x=A11.x;Aflame[i].y=A11.y+5;}
				if(A11.x<103){Aflame[i].x=A11.x;Aflame[i].y=A11.y;}
				if(A11.x>640){Aflame[i].x=A11.x;Aflame[i].y=A11.y;}
				Aflame[i].bdead=FALSE;
				Aflame[i].ftps =0;
			}
			A11.lifenum--;
			A11.planestatus=super;
			A11.x=400;
			A11.y=400;
			A11.direct=Aup;
		}
	}
	for(int j=0;j<cenemy;j++)
	{
		i=0;
		if(!Afire[j].bdead)
		{
			if(Afire[j].x<103||Afire[j].x>660||Afire[j].y<2||Afire[j].y>560)
			{
				if(Afire[j].type==Fplane)A11.bfire=FALSE;
                else{Aenemy[Afire[j].Efire].bfire =FALSE;}
                Afire[j].bdead=TRUE;

				while(!Aflame[i].bdead){i++;}
				if(i<cenemy)
				{
					if(Afire[j].y<15 ){Aflame[i].x=Afire[j].x-15;Aflame[i].y=Afire[j].y;}
					if(Afire[j].y>560){Aflame[i].x=Afire[j].x-15;Aflame[i].y=Afire[j].y;}
					if(Afire[j].x<110){Aflame[i].x=Afire[j].x;Aflame[i].y=Afire[j].y-20;}
					if(Afire[j].x>660){Aflame[i].x=Afire[j].x;Aflame[i].y=Afire[j].y-20;}
					Aflame[i].bdead=FALSE;
				    Aflame[i].ftps=0;
				}
			}
		}
	}
	for(i=0;i<cenemy;i++)
	{
		if(!Afire[i].bdead)
		{	
			GetRect(&drect,Afire[i].x,Afire[i].y,Afire[i].height,Afire[i].width);
		    if(Afire[i].type==Fplane)
			{
				for(int k=0;k<cenemy;k++)
				{
					if(!Aenemy[k].bdead)
					{
						GetRect(&srect,Aenemy[k].x,Aenemy[k].y,Aenemy[k].height,Aenemy[k].width);
						if(Hit(drect,srect))
						{
							int h=0;
                            while(!Aflame[h].bdead){h++;}
							if(h<cenemy)
							{
								Aflame[h].bdead=FALSE;
								Aflame[h].ftps=0;
								Aflame[h].x=Aenemy[k].x;
								Aflame[h].y=Aenemy[k].y;
							}
							Aenemy[k].bdead=TRUE;
							nsorce++;
							Afire[i].bdead=TRUE;
							A11.bfire=FALSE;
						}
					}
				}
			}
			else
			{
				if(A11.planestatus==super)return;
				if(!A11.bdead)
				{
					GetRect(&srect,A11.x,A11.y,A11.height,A11.width);
                    if(Hit(drect,srect))
					{
						int n=0;
						while(!Aflame[n].bdead){n++;}
						if(n<cenemy)
						{
							Aflame[n].bdead=FALSE;
							Aflame[n].ftps=0;
							Aflame[n].x=A11.x;
							Aflame[n].y=A11.y;
						}
						A11.lifenum--;
						A11.planestatus=super;
						A11.x=400;
						A11.y=400;
						A11.direct=Aup;

						Afire[i].bdead=TRUE;
						Aenemy[Afire[i].Efire].bfire=FALSE;
					}
				}
			}
		}
	}
}
//********************************************************
//Hit()检测两个矩形是否相互重叠
//********************************************************
bool Hit(RECT drect,RECT srect)
{
	int xcount,ycount;
	int xmax,ymax;

	xcount=abs((drect.left-srect.left));
	ycount=abs((drect.top-srect.top));

	if(drect.left<srect.left)xmax=4*(drect.right-drect.left)/5;
	else
		xmax=3*(srect.right-srect.left)/5;

	if(drect.top<srect.top)ymax=4*(drect.bottom-drect.top)/5;
	else
		ymax=4*(srect.bottom-srect.top)/5;

	if(xcount<xmax&&ycount<ymax)return TRUE;
	else
		return FALSE;
}
//******************************************************
//EnemyAI处理敌机的发射、躲避、追踪等各项动作
//******************************************************
//1.同一直线上优先处理。
//则正面相对的追踪的比例比背面相对的大。
//2.不在同一直线上,则以一定的半径为追踪范围。
//3.如果是子弹,则以一对同心环为躲避范围。
//同时正面躲避比背面躲避的机率大。
//4.敌机在中间区域飞行的机率高,因为这样比较容易追踪。
void EnemyAI(void)
{

	for(int i=0;i<cenemy;i++)
	{
		//避免于四周相撞
		if(!Aenemy[i].bdead)
		{
			if(Aenemy[i].x<100||Aenemy[i].x>660||Aenemy[i].y<10||Aenemy[i].y>560)			
			{
				if(Aenemy[i].direct==Aup   ){Aenemy[i].y=10 ;}
				if(Aenemy[i].direct==Adown ){Aenemy[i].y=560;}
				if(Aenemy[i].direct==Aleft ){Aenemy[i].x=100;}
				if(Aenemy[i].direct==Aright){Aenemy[i].x=660;}
				Aenemy[i].direct+=rand()%3;
				Aenemy[i].direct=Aenemy[i].direct%4;//注意对变量取值的定义
			//例如:direct代表方向所以不可能大于3(0、1、2、3代表一个方向)
				//所以需要对值进行检测。
			}
		}
		//发弹控制功能
		if(!Aenemy[i].bdead&&!Aenemy[i].bfire)
		{
			if((abs((Aenemy[i].y-A11.y))<10&&
				(((Aenemy[i].x-A11.x)>10&&(Aenemy[i].x-A11.x)<60&&Aenemy[i].direct==3)||
			     ((A11.x-Aenemy[i].x)>10&&(A11.x-Aenemy[i].x)<60&&Aenemy[i].direct==1)||
				 ((A11.x-Aenemy[i].x)>60&&(rand()%10==4)&&Aenemy[i].direct==1)||
				 ((Aenemy[i].x-A11.x)>60&&(rand()%10==4)&&Aenemy[i].direct==3)))||
				  (abs((Aenemy[i].x-A11.x))<10&&
				(((Aenemy[i].y-A11.y)>10&&(Aenemy[i].y-A11.y)<60&&Aenemy[i].direct==0)||
				 ((A11.y-Aenemy[i].y)>10&&(A11.y-Aenemy[i].y)<60&&Aenemy[i].direct==2)||
				 ((A11.y-Aenemy[i].y)>60&&(rand()%10==4)&&Aenemy[i].direct==2)||
				 ((Aenemy[i].y-A11.y)>60&&(rand()%10==4)&&Aenemy[i].direct==0))))
				 //三种情况
			{
				
				Aenemy[i].bfire=TRUE;

				int n=0;
				while(!Afire[n].bdead){n++;}

				if(n<cenemy)
				{
					Afire[n].bdead=FALSE;
					Afire[n].direct=Aenemy[i].direct;
					Afire[n].Efire=i;
					Afire[n].type=Fenemy;
					Afire[n].x=Aenemy[i].x+Aenemy[i].width/3;
					Afire[n].y=Aenemy[i].y+Aenemy[i].height/3;
				}
			}
		//追踪功能 
        if(abs(Aenemy[i].y-A11.y)<8)
		{
			if(((Aenemy[i].x-A11.x)<100&&(Aenemy[i].x-A11.x)>30)||((Aenemy[i].x-A11.x)>100&&(rand()%10==5)))
				Aenemy[i].direct=3;
			if(((A11.x-Aenemy[i].x)<100&&(A11.x-Aenemy[i].x)>30)||((A11.x-Aenemy[i].x)>100&&(rand()%10==5)))
				Aenemy[i].direct=1;
		}
		if(abs(Aenemy[i].x-A11.x)<8)
		{
			if(((Aenemy[i].y-A11.y)<100&&(Aenemy[i].y-A11.y)>30)||((Aenemy[i].y-A11.y)>100&&(rand()%10==5)))
				Aenemy[i].direct=0;
			if(((A11.y-Aenemy[i].y)<100&&(A11.y-Aenemy[i].y)>30)||((A11.y-Aenemy[i].y)>100&&(rand()%10==5)))
				Aenemy[i].direct=2;
		}
		//所处位置的控制功能,例如:是飞机大部分时间在中间部分飞行,以便飞机的追踪
		if(((Aenemy[i].x<200&&Aenemy[i].x>190)||
			(Aenemy[i].x>600&&Aenemy[i].x<610)||
			(Aenemy[i].y>500&&Aenemy[i].y<510)||
			(Aenemy[i].y<100&&Aenemy[i].y>90))&&
			(rand()%7==3))
		{
			Aenemy[i].direct+=rand()%10;
			Aenemy[i].direct=Aenemy[i].direct%4;
		}
		//对炸弹的躲避功能,以一定的半径为躲避范围。同时对不同的情况有不同的躲避几率。
		//if
		}
	}
}
//**********************************************************
//清屏clrscr()
//**********************************************************
void clrscr(DWORD color=RGB(0,0,0))
{
	DDBLTFX ddbltfx;
	ddbltfx.dwSize=sizeof(ddbltfx);
	ddbltfx.dwFillColor=color;
	lpddsprimary->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
	lpddsback->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
}
//*********************************************************
//WinMain();主函数
//*********************************************************
int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine
,int nCmdShow)
{
	MSG msg;

	hWnd=InitWin(hInstance,nCmdShow);
    if(hWnd==NULL)
	{
		MessageBox(hWnd,"failed in initwin","INITWIN",NULL);
		return FALSE;
	}
	if(FAILED(InitDraw()))
	{
		FreeObject();
		PostQuitMessage(WM_CLOSE);
		return FALSE;
	}

	if(FAILED(InitInput(hWnd)))
	{
		OutputDebugString("failed init input ");
		PostQuitMessage(WM_CLOSE);
		return FALSE;
	}
	if(FAILED(InitSound()))
	{
		OutputDebugString("failed in initsouund");
		PostQuitMessage(WM_CLOSE);
		return FALSE;
	}

	InitData();
	clrscr();
	while(1)
	{
		if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
		{
			if(!GetMessage(&msg,NULL,0,0))
				return msg.wParam;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else if(active)
		{
			UpFlame();
		}
		else
			WaitMessage();
	}
}
//*********************************************************
//WinProc()窗口处理函数
//*********************************************************
HRESULT CALLBACK WinProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
	char buf[256];

	switch(msg)
	{
	case WM_ACTIVATEAPP:
		active=wParam;
    	SetFocus(hWnd);
		break;
	case WM_SETCURSOR:
		SetCursor(NULL);
		return TRUE;
	case  WM_KEYDOWN:
		switch(wParam)
		{
		case VK_ESCAPE:
			PostQuitMessage(0);
			break;
		case VK_RETURN:		
			mciSendString( closemidi, buf, sizeof(buf), NULL);
			mciSendString(openmidi, buf, sizeof(buf), NULL);
			InitData();
			nsorce=0;
			gamerank=0;
			gamestatus=GamePass;
			InitPass();
			A11.bfire=FALSE;
			if(A11.bdead)A11.bdead=FALSE;
			else
				A11.bdead=TRUE;
			gamestatus=GameStart;
			break;
		}
		break;
	case WM_DESTROY:

		FreeObject();
		mciSendString(stopmidi,buf,sizeof(buf),NULL);
		mciSendString( closemidi, buf, sizeof(buf), NULL);
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hwnd,msg,wParam,lParam);
}
//******************************************************
//UpFlame()
//******************************************************
void UpFlame(void)
{
	thistickcount=GetTickCount();
	if((thistickcount-lasttickcount)<TimeValue)return;
	else
	{
		DrawMap();
//		GetInput();
        UpdataInputData();
		DrawFire();
        DrawPlane();
		DrawEnemy();
	    EnemyAI();
		CheckHit();
		DrawFlame();
		DataPro();
		InitPass();
		DrawText();
		Flip();
	    lasttickcount=thistickcount;
	}
	return;
}
//********************************************************
//Initpass()过关后数据处理
//********************************************************
void InitPass()
{
	int nok=0;
	if(gamestatus==GameStart)
	{
		for(int j=0;j<cenemy;j++)
		{
			if(Aenemy[j].bdead==TRUE)nok++;
		}
		if(nok==cenemy)
		{
			gamestatus=GamePass;
			A11.planestatus=super;
		}
	}

	if(gamestatus==GamePass)
	{
		gamerank++;
		if(gamerank>8)gamerank=8;
		for(int i=0;i<gamerank;i++)
		{			
			Aenemy[i].bfire =FALSE;
			Aenemy[i].bdead =FALSE;
			Aenemy[i].direct=rand()%4;
			Aenemy[i].x     =leftblank+rand()%560;
			Aenemy[i].y     =rand()%560;
		}
		gamestatus=GameStart;
	}
}
//********************************************************
//DrawText()桌面text控制
//********************************************************
void DrawText()
{
//	HRESULT rval;
//	RECT rect;
	HDC hdc;
	char temp[100];

	lpddsback->GetDC(&hdc);
/*
	if(gamestatus==GameLogo)
	{

		SetBkMode(hdc, TRANSPARENT);//设置透明映射方式.
		SetTextColor(hdc, RGB(100,100,0)); 
		sprintf(temp, "  FIGHY 0.6");
        TextOut(hdc,396,260,temp,strlen(temp));

		SetTextColor(hdc, RGB(0,200,100));
        TextOut(hdc,392,320,"子 弹:SPACE",12);
		TextOut(hdc,392,340,"结 束:ESC  ",12);

		SetTextColor(hdc, RGB(200,0,100));
        sprintf(temp, "作者:盛崇山 SCUT");
		TextOut(hdc, 350, 280, temp,strlen(temp));

		sprintf(temp, "E_M: sintler@263.net");
		TextOut(hdc, 350, 300, temp,strlen(temp));
	}
	else
	{*/
		SetBkMode(hdc, TRANSPARENT);//设置透明映射方式.
		SetTextColor(hdc, RGB(100,100,0)); 

		sprintf(temp, "    FIGHT 0.6");
		TextOut(hdc,0,360,temp,strlen(temp));

		SetTextColor(hdc, RGB(0,100,200)); 

        sprintf(temp, "  作者:盛崇山 ");
		TextOut(hdc,0,380, temp,strlen(temp));

        sprintf(temp, " 2001.10 SCUT");
		TextOut(hdc,0,400, temp,strlen(temp));

		SetTextColor(hdc, RGB(200,0,100));
		sprintf(temp, "sintler@263.net");
        TextOut(hdc, 0, 420, temp,strlen(temp));

        TextOut(hdc,0,440,"子 弹:SPACE",12);
		TextOut(hdc,0,460,"开 始: ENTER",12);
		TextOut(hdc,0,480,"结 束:ESC  ",12);

		if(gamestatus==GameOver)
		{	
			SetTextColor(hdc, RGB(200,250,0)); 

		    sprintf(temp, "GAME OVER");
	    	TextOut(hdc,360,300,temp,strlen(temp));
		}

		if(gamestatus==GameStart)
		{
		SetTextColor(hdc, RGB(200,0,0));
        sprintf(temp,"Lifenum:  %d",A11.lifenum);
		TextOut(hdc,0,0,temp,strlen(temp));
		
        sprintf(temp,"SORCE:  %6d",nsorce*100);
		TextOut(hdc,700,0,temp,strlen(temp));

        sprintf(temp,"PART:  %d",gamerank);
		TextOut(hdc,700,500,temp,strlen(temp));
		}

		lpddsback->ReleaseDC(hdc);
}

⌨️ 快捷键说明

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