C # - Threads, Timers and something else

2

I was trying to practice doing a game on the console before going to unity, or rather to boot with unity. Particularly I had problems making the enemies, I came to the conclusion that what controls the enemies is the time and the conditions they have. Because of this I tried to create a timer that did not work so in lines where read timespan skip it was something wrong.

The other way that occurred to me, because time span did not work was to use Thread.Sleep() , which is a pause of X amount of time. The problem that this presented was the following, when pressing a key the enemy that descends to hit us is accelerated by the pressing of the player's movements, because the conditions of if they are fulfilled quickly goes faster in sleep.

My questions are 2:

  • Could this be done in a single thread?
  • How are timers instantiated correctly?

    namespace juego_consola
    {
        class Program
        {
            static void Main(string[] args)
            {
    
            TimeSpan stop;
            TimeSpan start = new TimeSpan(DateTime.Now.Ticks);
            while (true)
            {
    
                stop = new TimeSpan(DateTime.Now.Ticks);
    
                interfaz.marco();
                jugador.imprimo("/A\", nave.navex+nave.mov, nave.navey);
    
    
    
    
                Thread hilo = new Thread(new ThreadStart(roca.atake));
                hilo.Start();
    
    
    
    
    
                ConsoleKeyInfo tecla = Console.ReadKey();
    
                if (tecla.Key == ConsoleKey.LeftArrow)
                {
    
                    nave.mov += -1;
                    if (nave.navex + nave.mov <= 2)
                    {
                        nave.mov = 0;
                        nave.navex = 2;
    
    
    
                        jugador.imprimo("/A\", nave.navex, nave.navey);
                        continue;
                    }
    
    
                    jugador.imprimo("/A\", nave.navex + nave.mov, nave.navey);
    
                }
                if (tecla.Key == ConsoleKey.RightArrow)
                {
    
                    nave.mov += 1;
                    if (nave.navex + nave.mov >= 56)
                    {
                        nave.mov = 0;
                        nave.navex = 55;
    
    
                        jugador.imprimo("/A\", nave.navex, nave.navey);
                        continue;
                    }
    
    
                    jugador.imprimo("/A\", nave.navex + nave.mov, nave.navey);
    
                }
    
    
            }
    
    
        }
    
    
    
    
    
    
    }
    
    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    class nave
    {
        public static int navex = 16;
        public static int navey = 21;
        public static int mov = 0;
    
    }
    class roca
    {
        public static int rokx = 15;
        public static int roky = 0;
        public static void atake()
        {
            //var t = new System.Timers.Timer(1000);
            //t.Elapsed += (sender, args) => roca.atake();
            //t.Start();
            while (roky<=21)
            {
    
    
                roca.roky += 1;
            jugador.imprimo("O", roca.rokx, roca.roky);
                Thread.Sleep(1000);
                interfaz.marco();
    
        }
        }
    }
    
    
    
    
    
    
    //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        class jugador
        {
            public static void imprimo(string s, int x, int y)
            {
                Console.SetCursorPosition(x, y);
                Console.WriteLine(s);
            }
    
    
    }
    
    
    
    class interfaz
    {
        public static void marco()
        {
    
    
    
            jugador.imprimo("████████████████████████████████████████████████████████████", 0, 0);
            jugador.imprimo("██                                                        ██", 0, 1);
            jugador.imprimo("██                                                        ██", 0, 2);
            jugador.imprimo("██                                                        ██", 0, 3);
            jugador.imprimo("██                                                        ██", 0, 4);
            jugador.imprimo("██                                                        ██", 0, 5);
            jugador.imprimo("██                                                        ██", 0, 6);
            jugador.imprimo("██                                                        ██", 0, 7);
            jugador.imprimo("██                                                        ██", 0, 8);
            jugador.imprimo("██                                                        ██", 0, 9);
            jugador.imprimo("██                                                        ██", 0, 10);
            jugador.imprimo("██                                                        ██", 0, 11);
            jugador.imprimo("██                                                        ██", 0, 12);
            jugador.imprimo("██                                                        ██", 0, 13);
            jugador.imprimo("██                                                        ██", 0, 14);
            jugador.imprimo("██                                                        ██", 0, 15);
            jugador.imprimo("██                                                        ██", 0, 16);
            jugador.imprimo("██                                                        ██", 0, 17);
            jugador.imprimo("██                                                        ██", 0, 18);
            jugador.imprimo("██                                                        ██", 0, 19);
            jugador.imprimo("██                                                        ██", 0, 20);
            jugador.imprimo("██                                                        ██", 0, 21);
            jugador.imprimo("██                                                        ██", 0, 22);
            jugador.imprimo("████████████████████████████████████████████████████████████", 0, 23);
            jugador.imprimo("/A\", nave.navex + nave.mov, nave.navey);
    
    
    
    
    
        }
    }
    

    }

asked by Shiki 31.07.2017 в 05:11
source

2 answers

3

You're a little confused about the use of timers and threads.

First of all, a timer creates a thread where every so often it executes the code that you indicate. You do not need to create a Thread manually.

Second the code you have commented on inside atake is the one that actually starts the timer, but you need to remove it and put it inside the function Main() outside the while . Initializing this will allow the atake method to be called every 1000 milliseconds.

Third. atake() now receives as parameter the timer since when a certain condition is met (in this case it seems to me that when it reaches the edge of the frame) the timer must be stopped. This is already controlled only with a if no longer with while

The code is more or less like this

static void Main()
{
    var timer = new Timer(1000);
    timer.Elapsed += (sender, args) => roca.atake(timer);
    timer.Start();

    while (true)
    {
        interfaz.marco();
        jugador.imprimo("/A\", nave.navex + nave.mov, nave.navey);
        ConsoleKeyInfo tecla = Console.ReadKey();

        if (tecla.Key == ConsoleKey.LeftArrow)
        // ...
    }
}

class roca
{
    public static int rokx = 15;
    public static int roky = 0;

    public static void atake(Timer timer)
    {
        roca.roky += 1;

        interfaz.marco();
        jugador.imprimo("O", roca.rokx, roca.roky);

        if (roky > 21)
        {
            timer.Stop();
        }
    }
}
    
answered by 31.07.2017 / 08:33
source
2

To create a Timer object you have to do the following:

Timer tActualizar = new Timer(Tick, "", 3600000, 3600000);

The first parameter is the callback function to which we are going to call. The second parameter is an object that we passed to the callback function (in my case, I passed it to an empty nstring). The third parameter is the time you wait for the first execution (in milliseconds). The fourth parameter is the interval of time that will pass between call and call to the callback function (in milliseconds).

What you will need is to define the callback function, it is declared as follows:

static void Tick(object data)
    {...}

The Tick method is where you would control the movement of the enemies if I am not mistaken and in the main thread is where you control the interaction with the user. I believe that Timer internally creates a thread separate from the main one.

I would say that with a single thread you can not do it, you need a Timer or at least 2 threads, one to control the movement of the enemies and another for the user's.

I hope I have helped.

    
answered by 31.07.2017 в 08:03