簡體   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