[英]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.