------------------------------BallisticSimulator---------------------
using System;
using System.Drawing;
namespace CannonBallGame
{
/// <summary>
/// A simple Ballistics simulator class
/// </summary>
public class BallisticSimulator
{
public float InitialAngle = 0.0f;
public float InitialVelocity = 100.0f;
public float ElapsedTime = 0.0f;
public float Timestep = 1.0f;
public BallisticSimulator()
{
}
/// <summary>
/// Gets the next position of the simulator by incrementing the ElapsedTime
/// </summary>
/// <returns>The next position as a PointF</returns>
public PointF GetNextPosition()
{
ElapsedTime += Timestep;
// Convert InitialAngle to radian, radian = degrees * (PI/180)
float fIA = InitialAngle * (float)(Math.PI/180.0f);
// Find X and Y values at time current
float fX = (float)((InitialVelocity * Math.Cos(fIA) * ElapsedTime)) / 2.0f;
float fY = (float)(((InitialVelocity * Math.Sin(fIA) * ElapsedTime) - (0.5f * 9.8f * (ElapsedTime * ElapsedTime))) / 2.0f);
PointF pt = new PointF(fX, fY);
return pt;
}
}
}
-------------------------CannonBallForm------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace CannonBallGame
{
public partial class CannonBallForm : Form
{
private int angle;
private int velocity;
private int height;
private Thread projectile;
private BallisticSimulator cannonSim;
// The next position to plot
private PointF pointNextPosition = new PointF();
// The size of the dot to draw
private SizeF projectileSize = new SizeF(5.0f, 5.0f);
public CannonBallForm()
{
InitializeComponent();
cannonSim = new BallisticSimulator();
}
///<summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
//Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new CannonBallForm());
}
private void Run()
{
try
{
Cannon c = new Cannon(graphicsPanel, angle, velocity, height);
c.fire();
}
catch (ThreadAbortException)
{ }
finally
{
bigRedButton.Enabled = true;
}
}
private void angleSelect_ValueChanged(object sender, EventArgs e)
{
angle = (int)angleSelect.Value;
}
private void velocitySelect_ValueChanged(object sender, EventArgs e)
{
velocity = (int)velocitySelect.Value;
}
private void heightSelect_ValueChanged(object sender, EventArgs e)
{
height = (int)heightSelect.Value;
}
private void bigRedButton_Click(object sender, EventArgs e)
{
bigRedButton.Enabled = false;
timer1.Enabled = true;
cannonSim.InitialAngle = angle;
cannonSim.InitialVelocity = velocity;
}
private void timer1_Tick(object sender, EventArgs e)
{
// On tick, increment simulator and plot next point on trajectory
PlotPoint(cannonSim.GetNextPosition());
}
public void Reset()
{
pointNextPosition = new Point(0, 0);
}
public void PlotPoint(PointF point)
{
pointNextPosition = point;
// We could invalidate just around this point for better performance
//graphicsPanel.Invalidate();
Graphics g = graphicsPanel.CreateGraphics();
// Setup a transform that puts (0,0) at the bottom left corner
Matrix xform = new Matrix();
xform.Scale(1.0f, -1.0f);
xform.Translate(0, -(graphicsPanel.Height - height));
g.Transform = xform;
// Smooooth!
g.SmoothingMode = SmoothingMode.AntiAlias;
// Draw the projectile
RectangleF rect = new RectangleF(pointNextPosition, projectileSize);
rect.Offset(-projectileSize.Width / 2.0f, -projectileSize.Height / 2.0f);
g.FillEllipse(Brushes.Blue, rect);
}
}
}