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

📄 a10.cpp

📁 用VC编写的飞机源程序!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		oldtime=GetTickCount();
		planenumber=planeremain;
		super=TRUE;
		cancontrol=FALSE;
		pos.x=backwidth/2-25;
		pos.y=backrect.bottom;
	}
	if (super==TRUE)
		if (GetTickCount()>oldtime+3000)//无敌时间3秒
			super=FALSE;

	if (cancontrol==FALSE)
	{
		if (pos.y>backrect.bottom-100) //飞机刚出现时是无法控制的
		{
			pos.y-=movespeed;
			Plane=1;
		}
		else
			cancontrol=TRUE;
	}
	else
	{
		//检测方向键
		Plane=1;
		if(GetAsyncKeyState(VK_UP))		{pos.y=pos.y-movespeed;}
		if(GetAsyncKeyState(VK_DOWN))	{pos.y=pos.y+movespeed;}
		if(GetAsyncKeyState(VK_LEFT))	{pos.x=pos.x-movespeed;Plane=0;}
		if(GetAsyncKeyState(VK_RIGHT))	{pos.x=pos.x+movespeed;Plane=2;}
	
		//范围检查
		if (pos.x<65)	pos.x=65;
		if (pos.x>backwidth-65-50)	pos.x=backwidth-65-50;
		if (pos.y<65)	pos.y=65;
		if (pos.y>backheight-65-60)	pos.y=backheight-65-60;
	}

	if (super==TRUE) //无敌时的闪烁效果
	{
		static int ot=0;//延时
		if (GetTickCount()-ot>30)
			ot=GetTickCount();
		else
			return;
	}

	//绘制飞机
	RECT rect;
	GetRect(&rect, pos.x, pos.y, 50, 60);
	HRESULT rval=lpDDSBack->Blt( &rect, lpDDSPlane[Plane], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
	if(rval == DDERR_SURFACELOST)    lpDDSBack->Restore();
}

//***************************************
//绘制背景地图
void DrawMap(void )
{
	//背景贴图的偏移坐标
	static int mapposX=64, mapposY=64;
	mapposX--;
	if (mapposX<=0 ) mapposX=64;
	
	if (Plane==0) mapposY--;
	if (Plane==2) mapposY++;
	if (mapposY<=0) mapposY=64;
	if (mapposY>64) mapposY=1;

	for (int x=0; x<=(int)backwidth/64; x++)
	for (int y=0; y<=(int)backheight/64; y++)
	{
		RECT rect;
		GetRect(&rect, 64*x-mapposY, 64*y-mapposX, 64, 64);

		HRESULT rval=lpDDSBack->Blt( &rect, lpDDSMap, NULL, DDBLT_WAIT, NULL);
		if(rval == DDERR_SURFACELOST)    lpDDSBack->Restore();
	}
}

//************************************
//绘制说明文字及图象
void DrawText(void )
{
	HRESULT rval;
	RECT rect;
	HDC hdc;
	char temp[100];
	
	if (gamestatus==GAME_LOG)//初始画面
	{
		lpDDSBack->GetDC(&hdc);
		SetBkMode(hdc, TRANSPARENT);
		SetTextColor(hdc, RGB(0,255,0)); 
			sprintf(temp, "A10 攻击机");
				TextOut(hdc, 200, 170, temp, strlen(temp));
	
			TextOut(hdc, 200, 240, "子  弹: Ctrl", 12);
			TextOut(hdc, 200, 260, "炸  弹: Space", 13);
			TextOut(hdc, 200, 280, "加  速:   +", 11);
			TextOut(hdc, 200, 300, "减  速:   -", 11);
			TextOut(hdc, 200, 320, "地  图: Return", 14);
			TextOut(hdc, 200, 340, "结  束: Esc", 11);

			SetTextColor(hdc, RGB(255,0,0));
			
		lpDDSBack->ReleaseDC(hdc);

		GetRect(&rect, 135, 150, 50, 50);
		rval=lpDDSBack->Blt( &rect, lpDDSPlane[1], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
			if(rval == DDERR_SURFACELOST)    lpDDSBack->Restore();
		GetRect(&rect, 292, 150, 50, 50);
		rval=lpDDSBack->Blt( &rect, lpDDSPlane[1], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
			if(rval == DDERR_SURFACELOST)    lpDDSBack->Restore();
	}

	if (gamestatus==GAME_START)//游戏进行中
	{
		for (int i=0; i<planeremain; i++)//绘制我机
		{
			GetRect(&rect, backrect.left+10+(i*25), backrect.bottom-30,20,20);
			rval=lpDDSBack->Blt( &rect, lpDDSPlane[1], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
			if(rval == DDERR_SURFACELOST)    lpDDSBack->Restore();
		}

		//绘制敌机
		GetRect(&rect, backrect.right-60, backrect.bottom-30,20,20);
		rval=lpDDSBack->Blt( &rect, lpDDSEnemy, NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
		if(rval == DDERR_SURFACELOST)    lpDDSBack->Restore();

		//总分
		lpDDSBack->GetDC(&hdc);
			SetBkMode(hdc, TRANSPARENT);
			SetTextColor(hdc, RGB(255,0,0)); 
			//得分
			sprintf(temp, "得分:%6d", enemylost*50);
			SetTextColor(hdc,RGB(0,255,0));
			TextOut(hdc, backwidth/2-40, 70, temp, strlen(temp));
			//击落敌机数
			sprintf(temp, "x%d", enemylost);
			TextOut(hdc, backrect.right-35, backrect.bottom-25, temp, strlen(temp));
			//帧频率
			SetTextColor(hdc, RGB(255,0,0));
			sprintf(temp, "%d帧 / 秒",fps);
			TextOut(hdc, 70, 70, temp, strlen(temp));
		lpDDSBack->ReleaseDC(hdc);
	}

	if (gamestatus==GAME_OVER)//游戏结束
	{
		lpDDSBack->GetDC(&hdc);
		SetBkMode(hdc, TRANSPARENT);
		SetTextColor(hdc, RGB(0,255,0)); 
			sprintf(temp, "共击落敌机 %d 架", enemylost);
			TextOut(hdc, backwidth/2-40, backheight/2-80, "Game Over", 9);
			TextOut(hdc, backwidth/2-55, backheight/2-30, temp, strlen(temp));
			TextOut(hdc, backwidth/2-50, backheight/2, "按回车键继续", 12);
			TextOut(hdc, backwidth/2-100, backheight/2+50, "A10攻击机 作者:王正盛 1998.12", 29);
		lpDDSBack->ReleaseDC(hdc);
	}
}

//****************************
//更新屏幕
void UpdateFrame(void )
{
	//检测发射子弹
	if(GetAsyncKeyState(VK_CONTROL) && gamestatus==GAME_START && cancontrol==TRUE )
	{
		static int newtime,oldtime=GetTickCount();
		newtime=GetTickCount();
		if (newtime>oldtime+100)
		{
			oldtime=newtime;
			buletposleft[bulet].x=pos.x+13;
			buletposleft[bulet].y=pos.y;
			buletposright[bulet].x=pos.x+32;
			buletposright[bulet].y=pos.y;
			bulet++;
			if (bulet==BULETNUMBER) bulet=0;
		}
	}

	//在后台页面上调用一系列绘制函数完成绘图工作
	DrawMap();
	//单色填充
	/*DDBLTFX ddbltfx; 
	ZeroMemory( &ddbltfx, sizeof(ddbltfx));
	ddbltfx.dwSize = sizeof(ddbltfx);
	ddbltfx.dwFillColor =DDColorMatch(lpDDSBack, RGB(255,0,0)) ;	// 
	lpDDSBack->Blt(
		NULL,        // 目标矩形
		NULL, NULL,  // 源页面和源矩形
		DDBLT_COLORFILL, &ddbltfx);
	*/
	CheckHit();
	DrawEnemy();
	DrawBom();
	DrawBulet();
	DrawPlane();
	DrawFlame();
	DrawText();
	//最后将后台页面换至前台
	Flip();
}

//********************************
//改变背景地图
void ChangeMap(void)
{
	static int b=0;
	if (b==0)
	{
		DDReLoadBitmap(lpDDSMap, "map2.bmp");
		b=1;
	}
	else if (b==1)
	{
		DDReLoadBitmap(lpDDSMap, "map3.bmp");
		b=2;
	}
	else if (b==2)
	{
		DDReLoadBitmap(lpDDSMap, "map1.bmp");
		b=0;
	}
}

//************************
//绘制炸弹
void DrawBom(void)
{
	static int bbom=0;
	
	for (int i=0; i<BOMNUMBER; i++)
	{
		if (bompos[i].y<0) continue;
		RECT rect;
		rect.left=bompos[i].x;
		rect.top=bompos[i].y;
		rect.right=rect.left+14;
		rect.bottom=rect.top+36;
	
		HRESULT rval=lpDDSBack->Blt( &rect, lpDDSBom[bbom], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
		if(rval == DDERR_SURFACELOST)    lpDDSFront->Restore();
		bompos[i].y-=3;
	}
		
	if (bbom==1) 
		bbom=0;
	else
		bbom=1;
}

//******************************************
//绘制子弹
void DrawBulet(void)
{
	for (int i=0; i<BULETNUMBER; i++)
	{
		RECT rectleft, rectright;
		rectleft.left=buletposleft[i].x;
		rectleft.top=buletposleft[i].y;
		rectleft.right=rectleft.left+5;
		rectleft.bottom=rectleft.top+13;
		rectright.left=buletposright[i].x;
		rectright.top=buletposright[i].y;
		rectright.right=rectright.left+5;
		rectright.bottom=rectright.top+13;
	
		HRESULT rval;
		rval=lpDDSBack->Blt( &rectleft, lpDDSBulet[0], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
			if(rval == DDERR_SURFACELOST)    lpDDSBack->Restore();
		rval=lpDDSBack->Blt( &rectright, lpDDSBulet[1], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
			if(rval == DDERR_SURFACELOST)    lpDDSBack->Restore();

		buletposleft[i].x--;
		buletposleft[i].y-=12;
		buletposright[i].x++;
		buletposright[i].y-=12;
	}
}

//*************************
//绘制敌机
void DrawEnemy(void)
{
	RECT rect;
	HRESULT rval;

	for (int i=0; i<ENEMYNUMBER; i++)
	{
		if (enemydead[i]!=0)//如果敌机未毁
		{
			switch (enemystyle[i])
			{
			case 0://敌机0
				GetRect( &rect, enemypos[i].x, enemypos[i].y, 35, 35);
				rval=lpDDSBack->Blt( &rect, lpDDSEnemy, NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
				if(rval == DDERR_SURFACELOST)    lpDDSBack->Restore();
	
				enemypos[i].y+=enemyspeed[i]+(movespeed-2);
				enemypos[i].x+=enemydir[i];
				break;
			case 1://子弹
				GetRect( &rect, enemypos[i].x, enemypos[i].y, 8, 8);
				rval=lpDDSBack->Blt( &rect, lpDDSBall, NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
				if(rval == DDERR_SURFACELOST)    lpDDSBack->Restore();
	
				enemypos[i].y+=enemyspeed[i]+(movespeed-2);
				enemypos[i].x+=enemydir[i];
				break;
			}
		}

		if (enemypos[i].y>backrect.bottom || enemydead[i]==0)
		{
			enemypos[i].x=(int)(forewidth*((long)rand()/32767.0)) +35;
			enemypos[i].y=(int)(35*((long)rand()/32767.0));
			enemyspeed[i]=(int)(4*((long)rand()/32767.0))+1;
			enemydir[i]=(int)(3*((long)rand()/32767.0))-1;//-1,0,1
			
			//敌机类型
			enemystyle[i]=(int)(2*((long)rand()/32767.0));//0,1
			enemydead[i]=1;//敌人复活
		}
	}
}

//******************************
//碰撞检测
void CheckHit(void)
{
	if (gamestatus!=GAME_START) return;//如果游戏结束

	//检测敌机是否被击落
	for (int e=0; e<ENEMYNUMBER; e++)
	{
		if (enemydead[e]==0) continue;//敌人已消灭
		switch (enemystyle[e])
		{
		case 1://是子弹
			break;
		case 0://是敌机
			if (OutOfRange(enemypos[e])) continue;//敌机不在窗口内
			for (int b=0; b<BULETNUMBER; b++)
			{
				//检测左子弹
				if (!OutOfRange(buletposleft[b]))
				{
					if (abs(enemypos[e].x-buletposleft[b].x+15)<10 && abs(enemypos[e].y-buletposleft[b].y+11)<10)
					{
						enemydead[e]=0;//使敌机销毁
						buletposleft[b].y=0;//使子弹消失
						flamepos[e].x=enemypos[e].x-10;//火焰坐标
						flamepos[e].y=enemypos[e].y-8;//火焰坐标
						flamestatus[e]=1;//火焰状态
						enemylost++;
						MessageBeep(0);
					}
				}
				//检测右子弹
				if (!OutOfRange(buletposright[b]))
				{
					if (abs(enemypos[e].x-buletposright[b].x+15)<10 && abs(enemypos[e].y-buletposright[b].y+11)<10)
					{
						enemydead[e]=0;//使敌机销毁
						buletposright[b].y=0;//使子弹消失
						flamepos[e].x=enemypos[e].x-10;//火焰坐标
						flamepos[e].y=enemypos[e].y-8;//火焰坐标
						flamestatus[e]=1;//火焰状态
						enemylost++;
						MessageBeep(0);
					}
				}
				//是敌机完
			}
		}
	}

	//检测我机是否撞毁
	if (super==FALSE)
	{
		for (int p=0; p<ENEMYNUMBER; p++)
		{
			if(enemydead[p]==0) continue;
			if (OutOfRange(enemypos[p])) continue;
			switch (enemystyle[p])
			{
			case 1://子弹
				if (abs(pos.x-enemypos[p].x+21)<15 && abs(pos.y-enemypos[p].y+26)<12)
				{
					enemydead[p]=0;
					deadflamepos.x=enemypos[p].x-29;
					deadflamepos.y=enemypos[p].y-29;
					deadflamestatus=1;
					planeremain--;
					MessageBeep(0);
				}
				break;
			case 0://敌机
				if (abs(pos.x-enemypos[p].x+7)<15 && abs(pos.y-enemypos[p].y+12)<12)
				{
					enemydead[p]=0;
					deadflamepos.x=enemypos[p].x-15;
					deadflamepos.y=enemypos[p].y-15;
					deadflamestatus=1;
					planeremain--;
					MessageBeep(0);
				}
				break;
			}
		}
	}
	
	if (planeremain==-1) //游戏结束
	{
		gamestatus=GAME_OVER;
		KillTimer(hWnd, TIMER_CHANGEMAP);
	}
}

//*************************
//检测物体是否超出边界
BOOL OutOfRange(POINT p)
{
	if (p.x<35 || p.x>WINDOW_WIDTH+35 || p.y<35 || p.y>WINDOW_HEIGHT+35)
		return TRUE;
	else
		return FALSE;
}

//******************
//填充一个RECT结构
void GetRect(RECT* rect, long left, long top, long width, long height)
{
	rect->left=left;
	rect->top=top;
	rect->right=left+width;
	rect->bottom=top+height;
	return;
}

//***************************************
//绘制爆炸火焰
void DrawFlame(void )
{
	//绘制敌机火焰
	for (int f=0; f<ENEMYNUMBER; f++)
	{
		if (flamestatus[f]!=0)
		{
			RECT rect,srect;
			GetRect(&rect, flamepos[f].x, flamepos[f].y, 54, 50);
			GetRect(&srect, (flamestatus[f]-1)*54, 0, 54, 50);

			HRESULT rval;//绘制火焰
			rval=lpDDSBack->Blt( &rect, lpDDSFlame, &srect, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
			if(rval == DDERR_SURFACELOST)    lpDDSBack->Restore();
			
			static int otime[ENEMYNUMBER];
			if (GetTickCount()-otime[f]>150)
			{
				otime[f]=GetTickCount();
				flamestatus[f]++;//更新火焰状态
				if (flamestatus[f]==11 ) flamestatus[f]=0;//火焰完毕
			}

		}
	}

	//绘制我机撞毁火焰
	if (deadflamestatus!=0)
	{
		RECT rect, srect;
		GetRect(&rect, deadflamepos.x, deadflamepos.y, 66, 66);
		GetRect(&srect,(deadflamestatus-1)*66, 0, 66, 66);

		HRESULT rval;//绘制火焰
		rval=lpDDSBack->Blt( &rect, lpDDSDead, &srect, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
		if(rval == DDERR_SURFACELOST)    lpDDSBack->Restore();
			
		static int oldtime=0;//延时
		if (GetTickCount()-oldtime>200)
		{
			oldtime=GetTickCount();
			deadflamestatus++;//更新火焰状态
			if (deadflamestatus==9 ) deadflamestatus=0;//火焰完毕
		}
	}
}

⌨️ 快捷键说明

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