Click here to Skip to main content
15,867,308 members
Articles / Desktop Programming / Windows Forms

A Simulation of a Canadian F-86 Fighter Jet in Windows Forms using Visual C++ 2005

Rate me:
Please Sign up or sign in to vote.
4.00/5 (9 votes)
29 May 2010CPOL2 min read 40.2K   1.6K   17   2
A Simulation of a Canadian F-86 fighter jet in Windows Forms using Visual C++ 2005
Image 1

Introduction

Why am I creating a simulation of an aircraft's flight instruments? The reason is because I grew up surrounded by jet and turboprop aircrafts and I've always wanted to replicate the dynamics of aircrafts on software.

The North American Aviation F-86 Sabre

Image 2

The F-86 Sabre is a fighter aircraft. Sabre is best known for its Korean War against the Soviet MiG-15. There have been more than 7,800 aircrafts between 1949 and 1956 and were by far the most-produced Western jet fighters, with a total production of all variants at 9,860 units. Variants were built in Canada and Australia. The Canadair Sabre added another 1,815 airframes, and the significantly redesigned CAC Sabre (sometimes known as the Avon Sabre or CAC CA-27), had a production run of 112.

Image 3

Specifications (F-86A):

Armament:Six .50-cal. machine guns and eight 5-in. rockets or 2,000 lbs. of bombs
Engine:One General Electric J47 turbojet of 5,200 lbs. thrust
Maximum speed:685 mph
Cruising speed:540 mph
Range:1,200 miles
Combat ceiling:49,000 ft.
Span:37 ft. 1 in.
Length:37 ft. 6 in.
Height:14 ft. 8 in.
Weight:13,791 lbs. loaded
Crew: One

Fast Forwarding a Bit

Designing apps in Microsoft Visual C++ 2005 Express Edition is pretty straight forward. Point this, click that, presto! Place it on the form. Components on the form align to rectangular grids, giving your apps a symmetric look.

Fast forwarding a bit, we've created a Windows Form, placed labels and pictureboxes on the form to have all these controls respond to mouse clicks, and key events, we have to put some code into it. So we double-click on any given control, place some code in that controls' event method.

KeyDown Event

The KeyDown event is called upon when a key is pressed down. The flight instruments and gauges respond accordingly by displaying the changes on the instruments. So when the user presses down the left, right, up or down key - the instruments and gauges will display tilting or banking.

C++
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 Event

The MouseMove event is called upon when the mouse is dragged or moved. The flight instruments and gauges respond accordingly by displaying the changes on the instruments. So when the mouse moves up, down, left, right, - the instruments and gauges will display the movements accordingly.

C++
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
		}
	}
}

The pictureBox1_Paint Event

The pictureBox1_Paint event is called upon to draw the gauges and instruments.

C++
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);
}

The draw_rpm( ) Method

The draw_rpm( ) method is called upon to display when the user increases the throttle to give it more gas, the needle in the RPM meter will respond accordingly.

C++
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;
  //
} 

The rpm_needle( PaintEventArgs^ e)

The rpm_needle( PaintEventArgs^ e) method is called upon to draw the needle of an RPM meter.

C++
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));
	}
} 

Please also have a look at C# Avionic Instrument Controls[^].

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Sweden Sweden
About me:
I attended programming college and I have a degree in three most famous and successful programming languages. C/C++, Visual Basic and Java. So i know i can code. And there is a diploma hanging on my wall to prove it.
.
I am a professional, I am paid tons of cash to teach or do software development. I am roughly 30 years old .

I hold lectures in programming. I have also coached students in C++, Java and Visual basic.

In my spare time i do enjoy developing computer games, and i am developing a rather simple flight simulator game
in the c++ programming language using the openGL graphics libray.

I've written hundreds of thousands of code syntax lines for small simple applications and games.

Comments and Discussions

 
GeneralHumm.. Pin
andre1234511-May-10 1:44
andre1234511-May-10 1:44 
GeneralRe: Thanks, i needed that file.. Pin
Software_Developer29-May-10 18:57
Software_Developer29-May-10 18:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.