我如何做倒计时并排运行主循环
本文关键字:运行 循环 何做 倒计时 | 更新日期: 2023-09-27 17:50:47
我正在用c#制作一个小型的主机应用游戏。问题是,你必须四处奔跑,收集金币。你必须在1分钟内完成,否则你会死。我让它工作的方式,我已经做了一个枚举,包括:运行,赢,输,结束语句。主循环运行时,游戏的游戏状态是:运行。比如:
switch (...) {
case PlayGame:
Console.Clear();
GameWorld gameWorld = new GameWorld();
gameWorld.Update();
while (gameWorld.GameState == GameState.Runs) {
gameWorld.PlayerMovement();
gameWorld.Update();
}
break;
case ...
}
现在一切都很好…最后一件事是,我必须制作这个"计时器",它会从1秒计数到60秒,并在给定坐标的屏幕上打印它。我试过很多不同的方法。例如,我在GameWorld类中创建了一个方法(游戏邦注:这是我拥有游戏核心的地方),并将其称为Time。我创建了一个变量Time,并给它赋值60。然后,我创建了一个for循环,将光标设置在给定的坐标上,编写每个循环上升的值,并设置Thread.Sleep(1000);最后一件事是……这基本上是每秒加1,直到它达到59。现在的问题是,当我在主循环(while)中运行这个方法时,它首先计数到60秒,然后运行低于60秒的东西。当我在while循环中的所有命令下面运行它时,也发生了同样的事情。你们知道我怎么才能让"倒计时"和主循环一起运行吗?谢谢你的回答和时间!
虽然可以启动一个单独的线程来连续运行计时器以使倒计时并行运行,但我只会跟踪开始时间并打印更新的秒数作为Update()
方法的一部分(或者在任何最有意义的地方,可能是在主游戏循环中单独调用方法)。
无论是第一次调用Update()
,当GameWorld
被创建时,甚至是一个新的Start()
方法,使用DateTime.UtcNow
存储当前时间,并在需要去的地方打印60。在下一次/后续更新中,获得新的当前时间,找出差值并从60秒中减去它,得到剩余时间。
编辑,多一点说明:
这里有一些代码可以让您开始,然后您可以插入对Start()
的调用和PrintCountdown()
在适当的地方,我想让你做尽可能多的工作:)。
class GameWorld {
...
DateTime startTime;
void Start() {
startTime = DateTime.UtcNow;
}
void PrintCountdown() {
DateTime currentTime = DateTime.UtcNow;
TimeSpan gameRunTime = currentTime - startTime;
int timeRemaining = 60 - gameRunTime.TotalSeconds();
// Whatever code you have to print the countdown time
}
...
}
编辑2:正如hatchet指出的,DateTime.UtcNow
比DateTime.Now
快得多。这对你的游戏来说可能无关紧要,但使用DateTime.UtcNow
可以减少游戏循环中的一些循环。
您可以在某个地方检查系统时钟(例如使用DateTime.Now
),并将其与程序的开始时间进行比较,检查60秒已经过去了。
你可以有一个定时器,它在指定的时间间隔ping你,你可以处理这个事件来做你的更新。示例
case PlayGame:
Console.Clear();
GameWorld gameWorld = new GameWorld();
gameWorld.Update();
//Timer to ping you every second
Timer aTimer = new Timer
{
Interval = 1000, //change this to fit your needs
Enabled = true
};
aTimer.Elapsed+=this.OnTimedEvent;
while (gameWorld.GameState == GameState.Runs)
{
gameWorld.PlayerMovement();
gameWorld.Update();
}
事件处理程序
private void OnTimedEvent(object sender, ElapsedEventArgs e)
{
//updates here?
}
编辑:如果范围是每秒钟运行运动60秒,那么使用秒表应该是最准确的方法。(它也会做很多循环…)
var gameWorld = new GameWorld ();
var stopwatch = Stopwatch.StartNew ();
gameWorld.Update();
for (var n = 0; n < 60;)
{
if ((int)(stopwatch.ElapsedMilliseconds / 1000) > n)
{
gameWorld.PlayerMovement ();
gameWorld.Update ();
++n;
Console.WriteLine ("{0}ms elapsed.", stopwatch.ElapsedMilliseconds);
}
Thread.Sleep(1);
}