[英]How do I use a timer/ delay to make an object or a character move in Console Window?
I'm trying to create a console game where character 'M' as in "Martian" and character 'S' as in "SpaceCreature" stay opposite on both ends on the X axis and move up and down across Y axis. 我正在尝试创建一个控制台游戏,其中“ Martian”中的角色“ M”和“ SpaceCreature”中的角色“ S”在X轴的两端相对,并在Y轴上上下移动。
I use arrow keys to make the 'M' move up and down. 我使用箭头键使'M'上下移动。 But the 'S' should also move but by itself whenever 'M' moves. 但是,只要“ M”移动,“ S”也应该移动,但其自身也应该移动。 I need to make the 'S' move at a slower pace to follow the 'M'. 我需要以较慢的速度移动“ S”以跟随“ M”。
As of now, I got 'M' moving up and down using arrow keys and 'S' is also moving at the same time. 截至目前,我已经使用箭头键上下移动了“ M”,并且“ S”也在同时移动。
I need to make the 'S' move slower . 我需要使“ S” 移动速度变慢 。 I have tried thread.Sleep, but that just makes the 'S' disappear and appear back like a glitch. 我尝试过thread.Sleep,但这只会使“ S”消失并像小故障一样出现。 I think I need to use something called "Console.keyAvailable" but I am finding it hard on where to place that function. 我认为我需要使用一个名为“ 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();
}
}
}
Did you try to put Thread.Sleep(100);
您是否尝试放入Thread.Sleep(100);
right after sY = mY;
在sY = mY;
and didn't work? 没用吗?
Changing sleep time to shorter times might work. 将睡眠时间更改为较短的时间可能会起作用。
Also: 也:
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)
}
You don't need another thread...play with this. 您不需要其他线程...玩这个。 Press the up/down arrows or escape to quit; 按上/下箭头或退出以退出。 you do NOT have to hold down the arrow keys for continued movement. 您无需按住箭头键即可继续移动。 You may also be interested in my Console Snake example. 您可能也对我的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" : " ");
}
}
----- EDIT ----- -----编辑-----
How do I make the 'M' movement by tapping up/ down arrow keys instead of making continuous movement? 如何通过点击上/下箭头键而不是连续移动来进行“ M”移动?
Change the "was a key pressed" block to: 将“按下按键”块更改为:
// 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;
}
}
Then delete the if (DateTime.Now >= m.nextMovement)
block so you are only left checking for the SpaceShip time below. 然后删除if (DateTime.Now >= m.nextMovement)
块,以便仅检查下面的SpaceShip时间。 Now your "M" should only move when you tap and/or hold down the arrow keys. 现在,仅当您点击和/或按住箭头键时,“ M”应该移动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.