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.
I use arrow keys to make the 'M' move up and down. But the 'S' should also move but by itself whenever 'M' moves. I need to make the 'S' move at a slower pace to follow the 'M'.
As of now, I got 'M' moving up and down using arrow keys and 'S' is also moving at the same time.
I need to make the 'S' move slower . I have tried thread.Sleep, but that just makes the 'S' disappear and appear back like a glitch. I think I need to use something called "Console.keyAvailable" but I am finding it hard on where to place that function.
//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);
right after 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.
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?
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. Now your "M" should only move when you tap and/or hold down the arrow keys.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.