N
N
Neofos2021-05-08 13:23:00
Command line
Neofos, 2021-05-08 13:23:00

How to get rid of visual glitches when multithreading in C# console?

I'm learning C# and for the sake of practice I decided to create a simple rpg game in the console. I wanted to implement the possibility of shooting for a character: you press a certain key, and a bullet flies out:

public static void Controls()
        {
            while (true) // Бесконечное выполнение
            {
                ConsoleKeyInfo pressedKey = Console.ReadKey();
                switch (pressedKey.Key)
                {
                    case ConsoleKey.LeftArrow:
                        MoveLeft();
                        break;
                    case ConsoleKey.RightArrow:
                        MoveRight();
                        break;
                    case ConsoleKey.UpArrow:
                        MoveUp();
                        break;
                    case ConsoleKey.DownArrow:
                        MoveDown();
                        break;
                    case ConsoleKey.Z: // Клавиша для стрельбы
                        new Thread(Fire).Start();
                        break;
                }
            }
        }


Placed the shooting method in a new thread so that the player can shoot as many times as he likes. The firing method itself looks like this:

private static Weapon weapon = new BasicPistol();

        private static void Fire()
        {
            // Рисуем игрока на том же месте, где он был,
            // чтобы вместо него не стояла "я" или "z"
            Console.SetCursorPosition(PosX, PosY);
            Console.Write(appearance);

            if (weapon != null)
            {
                weapon.Fire(PosX + 2, PosY);
            }
        }


The weapon class that the player fires looks like this:

class BasicPistol : Weapon
    {
        protected override double Damage { get; set; } = 10;

        // Кол-во пройденных клеток в секунду.
        protected override int ProjectileSpeed { get; set; } = 200;

        public override void Fire(int posX, int posY)
        {
            bool obstacleIsMet = posX == Map.BorderRight;

            while (obstacleIsMet == false)
            {
                Console.SetCursorPosition(posX, posY);
                Console.Write(Projectile); // Свойство из абстрактного класса Weapon

                // Затираем прежде нарисованную пульку
                Console.SetCursorPosition(posX - 1, posY);
                Console.WriteLine(' ');

                posX++;
                obstacleIsMet = posX == Map.BorderRight;

                Thread.Sleep(1000 / ProjectileSpeed);
            }

            // Стираем пульку при достижении края карты
            Console.SetCursorPosition(posX - 1, posY);
            Console.WriteLine(' ');
        }
    }


"Shooting" can do nothing but draw the flight of a bullet, but this is not so important now. It's okay if you shoot once or twice:

6096653aa922f361382439.png

But if the past bullet has not disappeared yet, and you shoot a lot, then such a terrible situation arises:

609665764729d886948359.png

I myself am not very experienced, so the question arises whether this can be fixed by retaining the player's ability to shoot repeatedly, without waiting for the previous bullet to disappear? I will be grateful for the help

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vasily Bannikov, 2021-05-08
@vabka

The input and draw cycle must occur on the same thread. You can not parallelize it, as you have now seen. In principle, it is possible to transfer physics and other calculations into separate threads, which depend little on the player.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question