这是我试图制作2D粒子模拟的代码片段
static long lastTime = 0;
static double GetDeltaTime()
{
long now = DateTime.Now.Millisecond;
double dT = (now - lastTime); // / 1000
lastTime = now;
Console.WriteLine(dT);
return dT;
}
应该很明显它将返回自上次调用该方法以来的时间(以毫秒为单位)。唯一的问题,这就是它打印的内容
393
1
0
0
0
0
0
0
0
0
0
...
好吧也许这就是因为每次通过时间不到一毫秒。所以我把它改成了
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;
}
但仍然打印
6.35476136625848E+17
20023
0
0
0
0
0
0
...
如果“粒子模拟器”不足以指示我的程序有多复杂,那么我只想说,完成传递需要比0个刻度更长的时间!
所以这里发生了什么?
-------代码参考------ 全体课程仅供参考
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;
}
}
}
另外,如果我对代码复杂程度的类比仍然不够,那么继续使用Particle2DSim类的更新方法
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
}
}
答案 0 :(得分:7)
问题是您正在使用DateTime
来衡量时间的流逝。 DateTime
用于表示日期和时间,但不用于衡量已用时间。
使用stopwatch
课程来衡量时间:
Stopwatch sw = new Stopwatch();
sw.Start();
// Do something here
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
// or sw.ElapsedTicks
有关差异的更多详细信息,请查看Eric Lippert的博客HERE
答案 1 :(得分:0)
using System;
class DeltaTimeExample
{
static void Main(string[] args)
{
DateTime time1 = DateTime.Now;
DateTime time2 = DateTime.Now;
// Here we find DeltaTime in while loop
while (true)
{
// This is it, use it where you want, it is time between
// two iterations of while loop
time2 = DateTime.Now;
float deltaTime = (time2.Ticks - time1.Ticks) / 10000000f;
Console.WriteLine(deltaTime); // *float* output {0,2493331}
Console.WriteLine(time2.Ticks - time1.Ticks); // *int* output {2493331}
time1 = time2;
}
}
}
答案 2 :(得分:0)
DeltaTime 类可帮助您实现动画。
public class DeltaTime
{
DateTime FirstTime;
public static DeltaTimer CreatePoint()
{
return new DeltaTime(){ FirstTime = DateTime.Now};
}
public TimeSpan GetDeltaTime()
{
if (FirstTime != null)
{
return DateTime.Now - FirstTime;
}
return TimeSpan.FromSeconds(1/60); //If null then return 60 FPS.
}
}
示例 1:
public async void TEST1_Animation(Button button)
{
var pointer= DeltaTime.CreatePoint();
for(double h = 0; h<button.Height;h++)
{
var n= pointer.GetDeltaTime().TotalSeconds;
h = h * n;
await button.Dispatcher.InvokeAsync(() => { button.Height= h; });
await Task.Delay(TimeSpan.FromSeconds(1 / 60 * n));
}
}
您的代码将如下所示:
static void Update()
{
var Pointer = DeltaTimer.CreatePoint();
while (true)
{
pSim.Update(Pointer.GetDeltaTime().TotalMilliseconds);
}
}
答案 3 :(得分:0)
class Program
{
static double DeltaTime;
static double Secondframe;
static double Counter;
static void Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
while (true)
{
TimeSpan ts = stopWatch.Elapsed;
double FirstFrame = ts.TotalMilliseconds;
DeltaTime = FirstFrame - Secondframe;
Counter += DeltaTime;
Console.WriteLine(Counter);
Secondframe = ts.TotalMilliseconds;
}
}
}
}