using System.Drawing; namespace MetoderUppgift { public partial class BilSimulation : Form { float velocity = 0; // [m/s] float vMax; // [m/s] float aMax; // [m/s^2] float engineBraking = 2; // [m/s^2] float dt = 1 / 50f; // 50 FPS float stripeOffset = 0; // horizontal offset for stripes public BilSimulation() { InitializeComponent(); Timer.Interval = (int)(1000 * dt); // s -> ms } void UpdateUI(float acceleration) { lblAcc.Text = "Acceleration: " + acceleration.ToString("0.00") + " [m/s²]"; lblVel.Text = "Hastighet: " + velocity.ToString("0.00") + " [m/s]"; lblThr.Text = "Gaspådrag: " + GetThrottlePercentage().ToString("0.00") + " [%]"; } void ImplementSpecifications() { if (float.TryParse(tbxAcceleration.Text, out float result)) // tal från sträng, värden blir NaN om input inte fungerar { aMax = result; } if (float.TryParse(tbxVelocity.Text, out float result2)) { vMax = result2; } } void Simulate() { ImplementSpecifications(); // Uppdatera specifikationer av bilen angivna av textboxes float acceleration = GetAcceleration(Throttle.Value); // Hämta acceleration velocity += acceleration * dt; // Uppdatera Acceleration UpdateUI(acceleration); // Uppdatera kontroller UpdateStripes(); // Uppdatera strecken på vägen för att simulera grafisk hastighet } void UpdateStripes() { stripeOffset += 20 * velocity * dt; // Uppdatera avstånd från initial plats för varje streck på vägen } float GetThrottlePercentage() //Omvanlda gaspådrag (0-4) till % { float percentage = (100 / Throttle.Maximum) * Throttle.Value; return percentage; } float GetAcceleration(int throttle) // Uppdatera accelerationen från gaspådrag { if (velocity < 0) { velocity = 0; return 0; // Undvik negativ hastighet } float ratio = (float)throttle / (float)Throttle.Maximum; float acceleration = ratio * aMax * (1.2f - velocity / vMax); // Formel för att göra fysik mer realistisk float netAcceleration = acceleration - engineBraking; return netAcceleration; } private void btnStart_Click(object sender, EventArgs e) //Start och stopp knapp { if (!Timer.Enabled) { Timer.Enabled = true; btnStart.Text = "Stopp"; } else { Application.Exit(); } } protected override void OnPaint(PaintEventArgs e) // Paint funktion för grafik { base.OnPaint(e); Graphics g = e.Graphics; int roadX = 400; int roadWidth = 100; g.FillRectangle(Brushes.DimGray, roadX, 0, roadWidth, ClientSize.Height); Car.Location = new Point(roadX + roadWidth / 2, ClientSize.Height / 2); Car.Size = new Size(roadWidth / 2, roadWidth / 2); // Streck int stripeWidth = 5; int stripeHeight = 15; int gap = 80; int stripesCount = 5; int stripeX = roadX + roadWidth / 2 - stripeWidth / 2; int stripeY = 0; if ((stripeOffset) > 80) { stripeOffset = 0; // Flytta tillbaka strecken om de hamnar utanför rutan. } for (int i = 0; i < stripesCount; i++) { g.FillRectangle(Brushes.White, stripeX, stripeY + stripeOffset, stripeWidth, stripeHeight); // Offset uppdateras varje tick. Förändringshastighet av hastighet. stripeY += gap; } } private void Timer_Tick(object sender, EventArgs e) { Simulate(); // Simulera fysik och grafik Invalidate(); // uppdatera grafik } private void Form1_Load(object sender, EventArgs e) { } private void lblMaxHastighet_Click(object sender, EventArgs e) { } } }