【问题标题】:Stopwatch c# game秒表 c# 游戏
【发布时间】:2021-07-27 20:16:30
【问题描述】:

我正在尝试在 C# 中创建 MAZE 游戏,但我对制作秒表有点困惑(我希望它从关卡开始时开始,并在胜利时停止)打印玩游戏的时间等级。我不明白在哪里以及如何正确添加它。所以这是我的主要游戏逻辑。

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;


namespace Labyrinth
{
    class Level
    {
        private Field gameField;
        private Player player;

        public Thread keyThread;
        public PressedKey key;

        public enum PressedKey
        {
            Left, Right, Up, Down, Fire, None
        }

        public bool Game;


        public Level(int level)
        {
            Console.CursorVisible = false;
            Game = true;
            StartThread();
            new LevelLoader(level).LoadField(out gameField, out player);
        }

        public void UpdateField()
        {
            PlayerAction();
            PutCharactersOnField();
            Thread.Sleep(50);
        }

        private void PutCharactersOnField()
        {
            for (int y = 0; y < gameField.Height; y++)
            {
                for (int x = 0; x < gameField.Width; x++)
                {
                    if (!(gameField[x, y] is Wall) && !((gameField[x, y] is Key)) && !((gameField[x, y] is Door)))
                    {
                        gameField[x, y] = new Empty();
                    }
                }
            }
            gameField[player.X, player.Y] = player;
        }

        private void PlayerAction()
        {
            int dx = 0, dy = 0;
            switch (key)
            {
                case PressedKey.Up:
                    dy = -1;
                    break;
                case PressedKey.Down:
                    dy = 1;
                    break;
                case PressedKey.Left:
                    dx = -1;
                    break;
                case PressedKey.Right:
                    dx = 1;
                    break;
            }

            player.Rotate(dx, dy);
            if (gameField.CanMakeStep(player.X + dx, player.Y + dy))
            {
                player.MakeStep(dx, dy);
                key = PressedKey.None;
            }
        }


        public void PrintLevel()
        {
            gameField.Print();
            player.Draw();
            LivesMessage();
            if (Door.count == 0)
            {
                Win();
            };
        }

        private void Win()
        {
            Game = false;
            keyThread.Interrupt();
            Console.Beep();
            Console.Clear();
            Console.WriteLine("COngrats! You win");
            Console.ReadKey();
            Help WinMenu = new Help();
            WinMenu.Menu();
        }

        private void ConsoleMessage(int x, int y, string message)
        {
            Console.SetCursorPosition(x, y);
            Console.Write(message);
        }

    

        private void LivesMessage()
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.BackgroundColor = ConsoleColor.Black;
            ConsoleMessage(0, gameField.Height + 1, "Doors Left: " + Door.count);
            ConsoleMessage(0, gameField.Height + 2, "Keys Left: " + Key.count);
        }

        private void StartThread()
        {
            key = PressedKey.None;
            keyThread = new Thread(KeysInput);
            keyThread.Start();
        }

        private void KeysInput()
        {
            while (Game)
            {
                var currntKey = Console.ReadKey(true);

                switch (currntKey.Key)
                {
                    case ConsoleKey.W:
                        key = PressedKey.Up;
                        break;
                    case ConsoleKey.UpArrow:
                        key = PressedKey.Up;
                        break;
                    case ConsoleKey.A:
                        key = PressedKey.Left;
                        break;
                    case ConsoleKey.LeftArrow:
                        key = PressedKey.Left;
                        break;
                    case ConsoleKey.D:
                        key = PressedKey.Right;
                        break;
                    case ConsoleKey.RightArrow:
                        key = PressedKey.Right;
                        break;
                    case ConsoleKey.S:
                        key = PressedKey.Down;
                        break;
                    case ConsoleKey.DownArrow:
                        key = PressedKey.Down;
                        break;
                    default:
                        key = PressedKey.None;
                        break;
                }
            }
        }
    }
}

我对此类主题非常陌生,因此我将不胜感激。我可以在哪里以及如何添加秒表? 我应该做一个秒表分隔的类还是只做一些方法?

    Stopwatch stopWatch = new Stopwatch(); 
    stopWatch.Start();
    for (int i = 0; i < 10; i++)
        Console.ReadKey();
 
    Console.WriteLine();
    stopWatch.Stop();]
 
    TimeSpan ts = stopWatch.Elapsed;
    Console.WriteLine($"{ts.Seconds:00}:{ts.Milliseconds:00}");
 
    Console.ReadKey();

【问题讨论】:

  • 小心使用 stopWatch.Elapsed,我想你想要:Console.WriteLine($"{ts.TotalSeconds:00}:{ts.Milliseconds:00}");

标签: c# maze stopwatch


【解决方案1】:

您根本不应该为此使用 Stopwatch,因为该类实际上是用于诊断的(线索是它的命名空间 System.Diagnostics)。

您对玩家玩您的游戏需要多长时间感兴趣,这可以通过DateTime 很好地完成。您可以将其中的 2 个与 Subtract 进行比较,它会返回一个 TimeSpan 的实例 - 您可以使用它来确定玩家玩游戏所花费的秒数/分钟数/时间。

在创建关卡时存储startTime(我假设这是游戏“开始”的点)

private DateTime startTime;

public Level(int level)
{
    Console.CursorVisible = false;
    Game = true;
    StartThread();
    new LevelLoader(level).LoadField(out gameField, out player);
    startTime = DateTime.UtcNow;
}

然后在游戏结束时将其与DaweTime.Now 进行比较(我假设这是在Win 内部,但也可能在其他地方):

private void Win()
{
    Game = false;
    keyThread.Interrupt();
    Console.Beep();
    Console.Clear();

    var timeTaken = DateTime.UtcNow.Subtract(startTime);
    Console.WriteLine($"You took {timeTaken.TotalSeconds} seconds");

    Console.WriteLine("COngrats! You win");
    Console.ReadKey();
    Help WinMenu = new Help();
    WinMenu.Menu();
}

【讨论】:

  • 我更喜欢 StopWatch 来测量时间,并且只是为了用户更改电脑时间或夏令时的可能性很小
  • 作为个人习惯(因为它更快)我通常使用DateTime.UtcNowDateTime.Now 时区信息必须计算并且不需要(因为它仅用于计算)。
  • @RandRandom:很好,但如果您的系统不支持高性能查询计数器it falls back to DateTime.UtcNow
  • @Oliver 我总是使用UtcNow——这就是我写Now的原因我不知道!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 2018-11-10
  • 2016-05-16
  • 1970-01-01
  • 2015-08-25
  • 1970-01-01
相关资源
最近更新 更多