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





4.00/5 (9投票s)
使用 Visual C++ 2005 在 Windows 窗体中模拟加拿大 F-86 战斗机
- 下载源代码 - 219.58 KB (Visual C++ 2005 Express 项目文件)

引言
我为什么要创建一个飞机飞行仪器的模拟程序?原因是,我从小就在喷气式飞机和涡轮螺旋桨飞机旁长大,并且一直想在软件上重现飞机的动态特性。
北美航空 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# 航空电子仪器控件[^]。