问题描述
因此,我尝试制作一个计时器,该计时器在单人游戏中从30秒滴答至0,但我不知道该怎么做。我是编程的新手。我正在尝试将其放入枚举,以便当计时器为0时将其状态从玩转为游戏结束。
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.pressed ||
Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
switch (currentGameState)
{
case Gamestate.Start:
timeSinceLastFrame += gameTime.ElapsedGameTime.TotalSeconds;
if (timeSinceLastFrame >= timeBetweenFrame)
{
timeSinceLastFrame -= timeBetweenFrame;
currentFrame.X++;
if(currentFrame.X >= sheetSize.X)
{
currentFrame.X = 0;
currentFrame.Y++;
if (currentFrame.Y>=sheetSize.Y)
{
currentFrame.Y = 0;
}
}
}
posstone.Y = posstone.Y + 1;
if (Keyboard.GetState().IsKeyDown(Keys.Enter))
{
currentGameState = Gamestate.Play;
}
break;
case Gamestate.Play:
break;
case Gamestate.GameOver:
break;
}
}
解决方法
方法1
我在游戏中使用了这种方法,在该游戏中,我存储了一个将来的DateTime来表示世界游戏时间,并带有一个未来的起点,并在Monobehaviour脚本的每个Unity物理框架上进行了更新。但是,可以在您的方案中使用一般思路。如果您不需要存储两次保存之间的游戏时间,那么这可能就太过分了。在这种情况下,请阅读方法2 。
您存储游戏当前时间的结束时间和参考时间(游戏时间)。您希望将它们都存储为类属性。
DateTime referenceTime;
DateTime endTime;
在将 currentGameState 设置为 Gamestate.Play 之前,您需要设置这些值
referenceTime = DateTime.Now; //Would be assigned from a global GameTime class object or your own custom game time
endTime = referenceTime.AddSeconds(30);
然后,您将在每个物理框架上更新参考时间。我使用毫秒而不是秒来获得准确性(GameTime Documentation),因为在大多数游戏引擎中,我使用帧更新的时间往往在几分之一秒之内。这将放置在 Gamestate.Play 案例分支
下referenceTime.AddMilliseconds(gameTime.ElapsedGameTime.TotalMilliseconds);
然后,您还需要在同一个case分支中进行检查(可能在最后一个代码片段之后)。
if (referenceTime > endTime) {
currentGameState = Gamestate.GameOver;
}
方法2
GameTime类具有替代成员 totalGameTime ,它也是System.TimeSpan结构值(GameTime Documentation,TimeSpan Documentation)。因此,这意味着另一个选择是您可以将从开始算起的总秒数用作游戏时间。参考值将再次存储为类成员,这次是 int ,因为我们将存储自游戏开始以来的秒数。
int referenceTime;
在将 currentGameState 切换为 Gamestate.Play 之前,您将设置参考时间。还有其他方法可以这样做,但这可能是最简单的。
referenceTime = gameTime.totalGameTime.TotalSeconds;
然后,您将在 Gamestate.Play 案例语句中添加一个检查。如果您打算反复使用 gameTime.totalGameTime.TotalSeconds ,那么您可能希望将其存储在另一个变量中,以提高可读性。
if (gameTime.totalGameTime.TotalSeconds > referenceTime + 30) {
currentGameState = Gamestate.GameOver;
}
,
您是否参加过System.Timer课程?
下面是该类的示例,因此您可以将其复制并粘贴到LinqPad中以进行运行和试验。
void Main()
{
/* What this does is raise an event every 5 seconds,according to value set in the interval
*/
var timer = new System.Timers.Timer(5000);
timer.Elapsed += OnTimedEvent;
timer.AutoReset = true; // Whether or not the event should be repeated
timer.Enabled = true; // Starts the timer
}
void OnTimedEvent(object sender,ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0:HH:mm:ss.fff}",e.SignalTime);
}