繁体   English   中英

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

[英]How do I use a timer/ delay to make an object or a character move in Console Window?

我正在尝试创建一个控制台游戏,其中“ Martian”中的角色“ M”和“ SpaceCreature”中的角色“ S”在X轴的两端相对,并在Y轴上上下移动。

我使用箭头键使'M'上下移动。 但是,只要“ M”移动,“ S”也应该移动,但其自身也应该移动。 我需要以较慢的速度移动“ 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();
      }
   }
}

您是否尝试放入Thread.Sleep(100); sY = mY; 没用吗?

将睡眠时间更改为较短的时间可能会起作用。

也:

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)
   }

您不需要其他线程...玩这个。 按上/下箭头或退出以退出。 您无需按住箭头键即可继续移动。 您可能也对我的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”应该移动。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM