65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Visual C++ 2005 在 Windows 窗体中模拟加拿大 F-86 战斗机

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (9投票s)

2010年5月10日

CPOL

2分钟阅读

viewsIcon

42175

downloadIcon

1585

使用 Visual C++ 2005 在 Windows 窗体中模拟加拿大 F-86 战斗机

引言

我为什么要创建一个飞机飞行仪器的模拟程序?原因是,我从小就在喷气式飞机和涡轮螺旋桨飞机旁长大,并且一直想在软件上重现飞机的动态特性。

北美航空 F-86 佩刀

F-86 佩刀是一种战斗机。佩刀最出名的是它在朝鲜战争中对抗苏联的米格-15。在 1949 年至 1956 年间,制造了超过 7,800 架飞机,并且是迄今为止产量最高的西方喷气式战斗机,所有型号的总产量为 9,860 架。变体型号在加拿大和澳大利亚制造。加拿大佩刀额外增加了 1,815 架飞机,而经过重大重新设计的 CAC 佩刀(有时称为埃文佩刀或 CAC CA-27)的产量为 112 架。

规格 (F-86A)

武器 六挺 .50 口径机枪和八枚 5 英寸火箭弹或 2,000 磅炸弹
Engine 一台通用电气 J47 涡轮喷气发动机,推力 5,200 磅
最大速度 685 英里/小时
巡航速度 540 英里/小时
Range 1,200 英里
作战高度 49,000 英尺
Span 37 英尺 1 英寸
长度 37 英尺 6 英寸
高度 14 英尺 8 英寸
权重 13,791 磅,满载
机组人员

快速推进

在 Microsoft Visual C++ 2005 Express Edition 中设计应用程序非常简单。 指向这个,点击那个,瞧! 将其放在窗体上。 窗体上的组件与矩形网格对齐,使您的应用程序看起来对称。

快速推进一下,我们创建了一个 Windows 窗体,在窗体上放置了标签和图片框,以便所有这些控件都响应鼠标单击和按键事件,我们必须在其中放入一些代码。 因此,我们双击任何给定的控件,并将一些代码放置在该控件的事件方法中。

KeyDown 事件

当按下某个键时,会调用 KeyDown 事件。 飞行仪器和仪表通过在仪器上显示变化来做出相应的响应。 因此,当用户按下向左、向右、向上或向下键时,仪器和仪表将显示倾斜或倾侧。

private: System::Void KeyDown(System::Object^  sender, 
	System::Windows::Forms::KeyEventArgs^  e)
{
	switch(e->KeyCode)
	{
		case System::Windows::Forms::Keys::Enter :
		break;

		case System::Windows::Forms::Keys::PageUp :
			rpm =rpm + delta_rpm; filter_rpm();
		break; //pgup

		case System::Windows::Forms::Keys::PageDown :
			rpm =rpm - delta_rpm;  filter_rpm();
		break;//pgdn

		case System::Windows::Forms::Keys::Up :
			alpha_tail =alpha_tail - delta_elevator;
			if (alpha_tail < -max_alpha_tail) alpha_tail  =   
							-max_alpha_tail;
		break;  //UpArw

		case System::Windows::Forms::Keys::Down :
			alpha_tail =alpha_tail + delta_elevator;
			if (alpha_tail > max_alpha_tail) alpha_tail   =   
							max_alpha_tail;
		break; //{ DwnArw }

		case System::Windows::Forms::Keys::Left  :
			alpha_aileron =alpha_aileron - (delta_aileron*rTrim);
			if (alpha_aileron < -max_aileron)  alpha_aileron  =  
							-max_aileron;
		break;    // { LftArw }

		case  System::Windows::Forms::Keys::Right :
			alpha_aileron =alpha_aileron + (delta_aileron*rTrim);
			if (alpha_aileron >max_aileron)  alpha_aileron   =   
							max_aileron;
		break; //   { RtArw }

		case  System::Windows::Forms::Keys::End :
			revertToInitialParameters();  ;
			break;//    { End }
		case  System::Windows::Forms::Keys::Home :// { Home }
					initialize_variables();

		break;

		case System::Windows::Forms::Keys::R 
				:/*set_rpm()*/; break; //  'R' : set_rpm();
		case System::Windows::Forms::Keys::P 
				:/*set_pitch()*/; break; //  'P' : set_pitch();
		case System::Windows::Forms::Keys::E
				:/*set_elevator()*/; break; //  'E' : set_elevator();
		case System::Windows::Forms::Keys::A 
				:/*set_aileron()*/;break;  //  'A' : set_aileron();
		case System::Windows::Forms::Keys::S 
				:/* set_mach()*/;break; //  'S' : set_mach();
		case System::Windows::Forms::Keys::W 
				:/*set_weight()*/; break; //  'W' : set_weight();
		case System::Windows::Forms::Keys::B 
				:/* set_bank()*/;break; //  'B' : set_bank();
		case 102:/*set_altitude()*/; break; //  'F' : set_altitude();
		case 104:/*set_heading()*/;break;  //  'H' : set_heading();
		case System::Windows::Forms::Keys::L:set_level(); 	
				break; //  'L' : set_level();
		case System::Windows::Forms::Keys::T: set_trim();
				break; //  'T' : set_trim();
		case System::Windows::Forms::Keys::Tab:debugon=-debugon;break;
	}
}

MouseMove 事件

当鼠标被拖动或移动时,会调用 MouseMove 事件。 飞行仪器和仪表通过在仪器上显示变化来做出相应的响应。 因此,当鼠标向上、向下、向左、向右移动时,仪器和仪表将相应地显示移动。

private: System::Void pictureBox1_MouseMove
	(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e)
{
	label26->Text=L"mx= "+System::Convert::ToString(e->X)+L"   
				my= "+System::Convert::ToString(e->Y);
	oldMouseX = mouseX;	oldMouseY = mouseY;	
				mouseX = e->X;	mouseY = e->Y;
	if (mouseNavigationEnabled)
	{
		if ((mouseX - oldMouseX) > 0)
		{
			 alpha_aileron =alpha_aileron + (delta_aileron*10);
			 if (alpha_aileron >max_aileron)  
			  alpha_aileron   =   max_aileron;// mouse moved to the right
		}
		else if ((mouseX - oldMouseX) < 0)
		{
			alpha_aileron =alpha_aileron - (delta_aileron*10);
			if (alpha_aileron < -max_aileron)  
			  alpha_aileron  =  -max_aileron;// mouse moved to the left
		}

		if ((mouseY - oldMouseY) > 0)
		{
			 alpha_tail =alpha_tail + (delta_elevator*10);
			 if (alpha_tail > max_alpha_tail) 
			  alpha_tail   =   max_alpha_tail; // mouse moved to the DOWN
		}
		else if ((mouseY - oldMouseY) < 0)
		{
			 alpha_tail =alpha_tail - (delta_elevator*10);
			 if (alpha_tail < -max_alpha_tail) 
			  alpha_tail  =   -max_alpha_tail; // mouse moved to the UP
		}
	}
}

pictureBox1_Paint 事件

调用 pictureBox1_Paint 事件来绘制仪表和仪器。

private: System::Void pictureBox1_Paint(System::Object^  sender, 
			System::Windows::Forms::PaintEventArgs^  e)
{
	horizon_bar(e);
	horizon_bar(e);
	alt_needle(e);
	t_and_b_needle(e);
	hsi_heading(e);
	rofc_needle(e);
	fuelflow_value(e);
	rpm_needle( e);
	draw_rpm( rpm_x,rpm_y, e);
	rpm_needle( e);
	rpmmeter(e);
	draw_n(e);
	draw_mach( );
	draw_tas(e);
	draw_ias(ias_x, ias_y, e);
	ias_needle(e);
	airspeed(e);
	hdi(e);
	draw_altitude(alt_x, alt_y,e);
	alt_needle(e);
	altimeter(e);  /*	draw_t_and_b(tab_x,tab_y,e );	 */
	t_and_b_needle( e);
	t_and_b( e);
	draw_heading( e);
	hsi_heading( e);
	hsi(e);
	draw_hdi(e);
	draw_rofc(roc_x, roc_y , e);
	rofc_needle(e);
	rofc( e);
	draw_fuelflow(e);
	fuelflow_value(e);
	ias_needle(e);  d
	raw_circles(e);
}

draw_rpm( ) 方法

当用户增加油门以提供更多燃油时,调用 draw_rpm( ) 方法来显示,RPM 计中的指针将相应地做出响应。

void gaugeSimulator::draw_rpm(int x, int y , PaintEventArgs^ e)
{
	label25->Text=L"rpmx="+System::Convert::ToString(rpm_x)+L", 
		rpmy=  "+System::Convert::ToString(rpm_y)+L",  
		x="+System::Convert::ToString(x)+L", y="+ System::Convert::ToString(y);
	rpm_last  =rpm;
	 e->Graphics->DrawLine( lineColor, rpm_x, rpm_y, x, y);
	rpm_lastx =x;
	rpm_lasty =y;
  //
} 

rpm_needle( PaintEventArgs^ e)

调用 rpm_needle( PaintEventArgs^ e) 方法来绘制 RPM 计的指针。

void gaugeSimulator::rpm_needle( PaintEventArgs^ e)
{
  double   x, y ;
  double z  ;

	z =rpm * (max_engine_rpm/100) * 16 * PI/10;
	x =rpm_x + (double)( 0.9 * rpm_r * Math::Cos(13*PI/10 - z) );
	y =rpm_y - (double)( 0.9 * rpm_r * Math::Sin(13*PI/10 - z) * gAR );

	label24->Text=L"rpmx="+System::Convert::ToString(rpm_x)+L", 
		rpmy=  "+System::Convert::ToString(rpm_y)+L",  
		x="+System::Convert::ToString(rpm_lastx)+L", 
		y="+ System::Convert::ToString(rpm_lasty);
	if  ( (Math::Abs(rpm_lastx - x) > 0)  ||  (Math::Abs(rpm_lasty - y) > 0) )
	{
	  e->Graphics->DrawLine( lineColor, rpm_x, rpm_y, rpm_lastx, rpm_lasty);
	  draw_rpm((int)x, (int)y+17,e);
	  label29->Text=System::Convert::ToString(Math::Round
				(rpm_last * max_engine_rpm,2));
	}
} 

另请参阅 C# 航空电子仪器控件[^]。

© . All rights reserved.