Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Delta Time Implementation

Tags:

c#

time

timedelta

Heres a code snippet from my attempt to make a 2D particle sim

static long lastTime = 0;
static double GetDeltaTime()
{
    long now = DateTime.Now.Millisecond;
    double dT = (now - lastTime); // / 1000
    lastTime = now;
    Console.WriteLine(dT);
    return dT;
}

It should be pretty obvious that it would return the time (in milliseconds) since the last time that method was called. Only problem, this is what it prints

393
1
0
0
0
0
0
0
0
0
0
...

Ok so maybe thats just because each pass is taking less than a millisecond. So i changed it to

    static long lastTime = 0;
    static double GetDeltaTime()
    {
        long now = DateTime.Now.Ticks; // Changed this to ticks
        double dT = (now - lastTime); // / 1000
        lastTime = now;
        Console.WriteLine(dT);
        return dT;
    }

but that still prints

6.35476136625848E+17
20023
0
0
0
0
0
0
...

and if "particle simulator" isnt a good enough indicator of how complex my program is, let me just say, it takes a lot longer than 0 ticks to complete a pass!

So whats going on here?

------- Code Reference ------ Heres the whole class just for reference

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace _2D_Particle_Sim
{
    static class Program
    {
        public static Particle2DSim pSim;
        static Form1 form;
        public static Thread update = new Thread(new ThreadStart(Update));

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]

        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            form = new Form1();

            pSim = new Particle2DSim(form);
            pSim.AddParticle(new Vector2(-80, -7), 5);
            pSim.AddParticle(new Vector2(8, 7), 3);

            Console.WriteLine("Opening Thread");

            Program.update.Start();

            Application.Run(form);

            // System.Threading.Timer timer;
            // timer = new System.Threading.Timer(new TimerCallback(Update), null, 0, 30);
        }

        static void Update()
        {
            GetDeltaTime();
            while (true)
            {
                pSim.Update(GetDeltaTime());
            }
        }

        static long lastTime = 0;
        static double GetDeltaTime()
        {
            long now = DateTime.Now.Ticks;
            double dT = (now - lastTime); // / 1000
            lastTime = now;
            Console.WriteLine(dT);
            return dT;
        }
    }
}

Also, if my analogy of how complex my code is still wasnt enough, heres the update methord from the Particle2DSim class

    public void Update(double deltaTime)
        {
              foreach (Particle2D particle in particles)
              {
                  List<Particle2D> collidedWith = new List<Particle2D>();

                  Vector2 acceleration = new Vector2();
                  double influenceSum = 0;

                  // Calculate acceleration due to Gravity
                  #region Gravity
                  foreach (Particle2D particle2 in particles)
                  {
                      double dist2 = particle.position.Distance2(particle.position);
                      double influence = dist2 != 0 ? particle2.mass / dist2 : 0;
                      acceleration.Add(particle.position.LookAt(particle2.position) * influence);
                      influenceSum += influence;

                      if (dist2 < ((particle.radius + particle2.radius) * (particle.radius + particle2.radius)) && dist2 != 0)
                      {
                          collidedWith.Add(particle2);
                      }
                  }
                  acceleration.Divide(influenceSum);
                  #endregion

                  particle.Update(deltaTime);

                  // Handle Collisions
                  #region Collisions
                  if (collidedWith.Count > 0)
                  {
                      Console.WriteLine("Crash!");

                      double newMass = 0;
                      double newRadius = 0;

                      Vector2 newPosition = new Vector2();
                      Vector2 newVelocity = new Vector2();

                      newMass += particle.mass;
                      newRadius += Math.Sqrt(particle.radius);

                      newPosition += particle.position;

                      newVelocity += particle.velocity * particle.mass;

                      particles.Remove(particle);

                      foreach (Particle2D particle2 in collidedWith)
                      {
                          newMass += particle2.mass;
                          newRadius += Math.Sqrt(particle2.radius);

                          newPosition += particle2.position;

                          newVelocity += particle2.velocity * particle2.mass;

                          particles.Remove(particle2);
                      }

                      newPosition.Divide(collidedWith.Count + 1);
                      newVelocity.Divide(newMass);

                      AddParticle(newPosition, newVelocity, newMass, newRadius);
                  }
                  #endregion
              } 
        }
like image 795
KWG Avatar asked Sep 29 '14 22:09

KWG


1 Answers

The problem is that you're using DateTime to try to measure the passage of time. DateTime is meant for representing a date and time, but not for measuring elapsed time.

Use the stopwatch class for measuring time:

Stopwatch sw = new Stopwatch();

sw.Start();

// Do something here

sw.Stop();

Console.WriteLine(sw.ElapsedMilliseconds);
// or sw.ElapsedTicks

For more details on the difference, check out Eric Lippert's blog HERE

like image 85
Rufus L Avatar answered Sep 20 '22 01:09

Rufus L