为了账号安全,请及时绑定邮箱和手机立即绑定

我如何使用计时器/延迟使对象或角色在控制台窗口中移动?

我如何使用计时器/延迟使对象或角色在控制台窗口中移动?

C#
慕慕森 2022-12-24 12:11:15
我正在尝试创建一个控制台游戏,其中“Martian”中的字符“M”和“SpaceCreature”中的字符“S”在 X 轴的两端保持相对,并在 Y 轴上上下移动。我使用箭头键使“M”上下移动。但是“S”也应该移动,但只要“M”移动,它就会自己移动。我需要让“S”以较慢的速度移动以跟随“M”。截至目前,我使用箭头键让“M”上下移动,“S”也在同时移动。我需要让 'S'移动得更慢。我试过 thread.Sleep,但这只会让“S”消失并像故障一样重新出现。我想我需要使用一个名为“Console.keyAvailable”的东西,但我发现很难确定该功能的位置。//X and Y get set constructors are defined in the abstract class:-SpaceObject public override void Draw()  //In both classes Martian and SpaceCreature{   Console.SetCursorPosition(X, Y);   Console.WriteLine("S");     //In Martian class:- Console.WriteLine("M");}static void Main(string[] args){   var m = new Martian(100, 10);   var s = new SpaceShip(100, 10);   const int MaxY = 25;   m.Draw();  //Abstract override void method   s.X = m.X + 100;   s.Y = m.Y;   s.Draw(); //Abstract override void method   ConsoleKeyInfo keyInfo;   while (true)   {      keyInfo = Console.ReadKey(true);      Console.Clear();      switch (keyInfo.Key)      {         case ConsoleKey.UpArrow:         if (m.Y > 0)         {            m.Y--;         }         break;         case ConsoleKey.DownArrow:         if (m.Y < MaxY)         {            m.Y++;         }         break;         }         m.Draw();         s.X = m.X + 100;         s.Y = m.Y;         s.Draw();      }   }}
查看完整描述

2 回答

?
米脂

TA贡献1836条经验 获得超3个赞

你不需要另一个线程......玩这个。按向上/向下箭头或退出退出;您不必按住箭头键继续移动。您可能还对我的Console Snake示例感兴趣。

class Program

{


    enum Directions

    {

        Up,

        Down,

        None

    }


    static void Main(string[] args)

    {

        DateTime next;     

        bool quit = false;

        ConsoleKeyInfo cki;

        Directions direction = Directions.None;


        Console.Clear();

        Console.CursorVisible = false;

        var m = new Martian();

        var s = new SpaceShip();

        m.Draw(true);

        s.Draw(true);

        do

        {

            // wait for next keypress, or next movement

            next = new DateTime(Math.Min(m.nextMovement.Ticks, s.nextMovement.Ticks));               

            while(!Console.KeyAvailable && DateTime.Now < next)

            {

                System.Threading.Thread.Sleep(10);

            }

            // was a key pressed?

            if (Console.KeyAvailable)

            {

                cki = Console.ReadKey(true);

                switch (cki.Key)

                {

                    case ConsoleKey.UpArrow:

                        direction = Directions.Up;

                        break;


                    case ConsoleKey.DownArrow:

                        direction = Directions.Down;

                        break;


                    case ConsoleKey.Escape:

                        quit = true;

                        break;

                }

            }

            // does anything need to move?

            if (DateTime.Now >= m.nextMovement)

            {

                switch(direction)

                {

                    case Directions.Up:

                        m.MoveUp();

                        break;


                    case Directions.Down:

                        m.MoveDown();

                        break;


                    case Directions.None:

                        m.UpdateNextMovement();

                        break;

                }

            }

            if (DateTime.Now >= s.nextMovement)

            {

                s.MoveToward(m);

            }

        } while (!quit);          

    }

}


public abstract class SpaceObject

{

    public int X;

    public int Y;

    public int MovementDelay;

    public DateTime nextMovement;


    abstract public void Draw(bool Visible);


    public void MoveUp()

    {

        if (this.Y > 0)

        {

            this.Draw(false);

            this.Y--;

            this.Draw(true);     

        }

        this.UpdateNextMovement();

    }


    public void MoveDown()

    {

        if (this.Y < Console.WindowHeight - 1)

        {

            this.Draw(false);

            this.Y++;

            this.Draw(true);       

        }

        this.UpdateNextMovement();

    }


    public void MoveToward(SpaceObject so)

    {

        if (so.Y < this.Y)

        {

            this.MoveUp();

        }

        else if (so.Y > this.Y)

        {

            this.MoveDown();

        }

        else

        {

            this.UpdateNextMovement();

        }

    }


    public void UpdateNextMovement()

    {

        this.nextMovement = DateTime.Now.AddMilliseconds(this.MovementDelay);

    }


}


public class Martian : SpaceObject

{


    public Martian()

    {

        this.X = 1;

        this.Y = Console.WindowHeight / 2;

        this.MovementDelay = 100;

        this.nextMovement = DateTime.Now.AddMilliseconds(this.MovementDelay);

    }


    public override void Draw(bool Visible)

    {

        Console.SetCursorPosition(this.X, this.Y);

        Console.Write(Visible ? "M" : " ");

    }


}


public class SpaceShip : SpaceObject

{


    public SpaceShip()

    {

        this.X = Console.WindowWidth - 2;

        this.Y = Console.WindowHeight / 2;

        this.MovementDelay = 750;

        this.nextMovement = DateTime.Now.AddMilliseconds(this.MovementDelay);

    }


    public override void Draw(bool Visible)

    {

        Console.SetCursorPosition(this.X, this.Y);

        Console.Write(Visible ? "S" : " ");

    }


}

- - - 编辑 - - -


如何通过点击向上/向下箭头键而不是连续移动来进行“M”移动?


将“按下一个键”块更改为:


            // was a key pressed?

            if (Console.KeyAvailable)

            {

                cki = Console.ReadKey(true);

                switch (cki.Key)

                {

                    case ConsoleKey.UpArrow:

                        m.MoveUp();

                        break;


                    case ConsoleKey.DownArrow:

                        m.MoveDown();

                        break;


                    case ConsoleKey.Escape:

                        quit = true;

                        break;

                }

            }

然后删除该if (DateTime.Now >= m.nextMovement)块,这样您就只剩下检查下面的 SpaceShip 时间了。现在你的“M”应该只在你点击和/或按住箭头键时移动。


查看完整回答
反对 回复 2022-12-24
?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

你有没有试着把它放在Thread.Sleep(100);后面s.Y = m.Y;但没有用?


将睡眠时间更改为更短的时间可能会奏效。


还:


while (true)

   {

      keyInfo = Console.ReadKey(true);

      Console.Clear();

      switch (keyInfo.Key)

      {

         case ConsoleKey.UpArrow:

         if (m.Y > 0)

         {

            m.Y--;

         }

         break;

         case ConsoleKey.DownArrow:

         if (m.Y < MaxY)

         {

            m.Y++;

         }

         break;

         }

      }

      m.Draw();

      s.X = m.X + 100;

      s.Y = m.Y;

      s.Draw(); //i think is better to put draw functions outside switch(key)

   }


查看完整回答
反对 回复 2022-12-24
  • 2 回答
  • 0 关注
  • 61 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信