Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: SrCooper en 7 Julio 2013, 00:13 am



Título: Duda con temporizador en C++
Publicado por: SrCooper en 7 Julio 2013, 00:13 am
Buenas, estoy haciendo un videojuego en C++ con allegro, y me gustaría ejecutar una función 3 segundos después de que se haya ejecutado otra. (Es decir ejecutar una función, esperar tres segundos, y ejecutar la otra.)

No quiero usar la función rest(3000), porque esto ralentiza el juego al estar ejecutandose en un bucle while.
Quisiera saber si hay alguna libreria o algún truco que me sirva. He buscado en google un poco, pero no encuentro mi problema en particular.

Un saludo y gracias de antemano ;D


Título: Re: Duda con temporizador en C++
Publicado por: amchacon en 7 Julio 2013, 00:16 am
¿Te refieres a una función que se ejecute cada 3 segundos?


Título: Re: Duda con temporizador en C++
Publicado por: SrCooper en 7 Julio 2013, 00:25 am
¿Te refieres a una función que se ejecute cada 3 segundos?

Ya encontré como hacer eso, pero no es a lo que me refiero. Lo que me gustaría es algo como así:
Código
  1. void funcion_principal(){
  2.       funcion1();
  3.       esperar(3);
  4.       funcion2();
  5. }

Y luego en el main poder llamar a "funcion_principal" y que esta se ejecute en ese orden y con ese tiempo. No se si me explico... :xD
Un saludo


Título: Re: Duda con temporizador en C++
Publicado por: amchacon en 7 Julio 2013, 00:29 am
Y luego en el main poder llamar a "funcion_principal" y que esta se ejecute en ese orden y con ese tiempo. No se si me explico... :xD
Pues no xD.

Aver, main llama a funcion_principal(). En funcion_principal() llama a funcion1(), espera 3 segundos y después llama a funcion2().

Si es eso, solo tendrías que poner rest(3000), si no es eso entonces no te entiendo... A no ser que quieras que la función y el main se ejecuten al mismo tiempo (¿Es eso?)


Título: Re: Duda con temporizador en C++
Publicado por: SrCooper en 7 Julio 2013, 00:46 am
Pues no xD.

Aver, main llama a funcion_principal(). En funcion_principal() llama a funcion1(), espera 3 segundos y después llama a funcion2().

Si es eso, solo tendrías que poner rest(3000), si no es eso entonces no te entiendo... A no ser que quieras que la función y el main se ejecuten al mismo tiempo (¿Es eso?)

Exacto, lo has entendido perfectamente. Es justo eso lo que quiero que haga, pero NO puedo usar el rest porque entonces se para TODO el juego y yo solo quiero que se pare esa función.

Mi idea es que mientras se esperan 3 segundos el while se ejecute normalmente las veces que haga falta y cuando haya pasado el tiempo se ejecute funcion2.

Un saludo


Título: Re: Duda con temporizador en C++
Publicado por: amchacon en 7 Julio 2013, 01:02 am
Es decir, una tarea en segundo plano.

Pues la manera más sencilla (relativamente) es usando threads (hilos). C++ tiene una clase para threads pero es relativamente nueva (no todos los compiladores están actualizados con ella).

Asi que te hago un ejemplo con las Windows API:

Código
  1. #include <winalleg.h>
  2.  
  3.  
  4. DWORD WINAPI Funcion( LPVOID lpParam )
  5. {
  6.  Funcion1();
  7.  rest(3000);
  8.  Funcion2();
  9. }
  10.  
  11. int main()
  12. {
  13.   //...
  14.   CreateThread(NULL,0,Funcion,NULL, 0,NULL);  
  15.  
  16.  while(!key[KEY_ESC] && !choque )
  17.  {{/code]


Título: Re: Duda con temporizador en C++
Publicado por: SrCooper en 7 Julio 2013, 01:10 am
Vale, entonces cuando en el while yo ejecute Funcion, esta se ejecutará automáticamente en segundo plano, ¿no?

La verdad es que no entiendo muy bien todo eso de DWORD, LPVOID y lpParam. ¿Qué significan exactamente?

Ya verás, ahora con esto mi juego del Snake va a mejorar mucho xDD
Un saludo y gracias :D


Título: Re: Duda con temporizador en C++
Publicado por: amchacon en 7 Julio 2013, 01:14 am
Vale, entonces cuando en el while yo ejecute Funcion, esta se ejecutará automáticamente en segundo plano, ¿no?
Desde el momento de CreateThread, se ejecutarán en segundo plano.

La verdad es que no entiendo muy bien todo eso de DWORD, LPVOID y lpParam. ¿Qué significan exactamente?
Son expresiones que se han inventado los de microsoft... Son tan especialitos, su equivalencia es la siguiente:

DWORD = unsigned int
LPVOID = void*

Y lpParam es el nombre que le he puesto al parámetro de la función (se le puede pasar un parámetro al hilo), también le podría haber puesto "habichuelas".

Te recomiendo que hagas algunas prácticas con hilos... Si tienes linux mejor (ahí tienes la librería pthread que es más fácil que Windows API).


Título: Re: Duda con temporizador en C++
Publicado por: amchacon en 7 Julio 2013, 01:19 am
Desde el momento de CreateThread, se ejecutarán en segundo plano.
Una nota sobre esto, cuando la función del hilo termine también terminará la tarea.

Si quieres que se repita continuamente tendrías que poner un while:

Código
  1. DWORD WINAPI Funcion( LPVOID lpParam )
  2. {
  3.  while(true)
  4.  {
  5.      Funcion1();
  6.      rest(3000);
  7.      Funcion2();
  8.  }
  9. }


Título: Re: Duda con temporizador en C++
Publicado por: SrCooper en 7 Julio 2013, 01:23 am
Te recomiendo que hagas algunas prácticas con hilos... Si tienes linux mejor (ahí tienes la librería pthread que es más fácil que Windows API).

Eso voy a hacer la verdad, porque es la primer vez que oigo de su existencia y me podrían ser muy útiles. Sí, tengo linux, pero por alguna razón no me funciona bien allegro así que utilizaré windows.
Un saludo y gracias por todo :P



Título: Re: Duda con temporizador en C++
Publicado por: OmarHack en 7 Julio 2013, 01:30 am
Si prefieres un for aquí lo tienes a lo ansi. XD
Código
  1. #include <iostream>
  2. void funcionEspera(int);
  3. int segundosEspera = 3;
  4. void funcion1(void);
  5. void funcion2(void);
  6. void funcion3(void);
  7.  
  8. int main()
  9. {
  10. funcion1();
  11. funcionEspera(2);
  12. funcion1();
  13. funcionEspera(segundosEspera);
  14. funcion2();
  15. funcionEspera(segundosEspera);
  16. funcion3();
  17. funcionEspera(3);
  18. return 0;
  19. }
  20. void funcionEspera(int segundosEspera)
  21. {
  22.      for(time_t i = (time(NULL) + segundosEspera); time(NULL) != i;);
  23. }
  24. void funcion1(void)
  25. {
  26. std::cout << "Asi te servira, espera..." <<std::endl;
  27. }
  28. void funcion2(void)
  29. {
  30. std::cout << ":)";
  31. std::cout <<std::endl << "introduce un numero para esperar por ultima vez el tiempo que indiques:";
  32. std::cin >> segundosEspera;
  33. }
  34. void funcion3 (void)
  35. {
  36. std::cout << std::endl << "Chau SrCooper xDDD";
  37. }


Título: Re: Duda con temporizador en C++
Publicado por: amchacon en 7 Julio 2013, 01:37 am
¿? Eso es como si pusieras un rest(3000) pero más complicado y con mucho peor rendimiento xD.

Pero sí, es muy imaginativo  ;)


Título: Re: Duda con temporizador en C++
Publicado por: OmarHack en 7 Julio 2013, 01:41 am
¿? Eso es como si pusieras un rest(3000) pero más complicado y con mucho peor rendimiento xD.

Pero sí, es muy imaginativo  ;)
¿rest de que librería es? Así lo implemento en un par de códigos. :P
Lo bueno es que así el usuario puede seleccionar el tiempo a esperar (en caso de que se necesitara).


Título: Re: Duda con temporizador en C++
Publicado por: amchacon en 7 Julio 2013, 01:47 am
¿rest de que librería es? Así lo implemento en un par de códigos. :P
Lo bueno es que así el usuario puede seleccionar el tiempo a esperar (en caso de que se necesitara).
rest es de Allegro pero tiene su equivalente en cualquier librería/SO:

- Windows API:

Código
  1. #include <windows.h>
  2.  
  3. Sleep(milisegundos); // duerme unos milisegundos

- Linux:

Código
  1. #include <pthread.h>
  2.  
  3. sleep(milisegundos); // La S aqui es minuscula

- SDL:

Código
  1. SDL_Delay(milisegundos);


Manejar el tiempo durmiendo es mucho más eficiente que contar el tiempo, al dormir el SO puede usar el procesador en otras cosas  ;)


Título: Re: Duda con temporizador en C++
Publicado por: OmarHack en 7 Julio 2013, 01:50 am
rest es de Allegro pero tiene su equivalente en cualquier librería/SO:

- Windows API:

Código
  1. #include <windows.h>
  2.  
  3. Sleep(milisegundos); // duerme unos milisegundos

- Linux:

Código
  1. #include <pthread.h>
  2.  
  3. sleep(milisegundos); // La S aqui es minuscula

- SDL:

Código
  1. SDL_Delay(milisegundos);


Manejar el tiempo durmiendo es mucho más eficiente que contar el tiempo, al dormir el SO puede usar el procesador en otras cosas  ;)
Cierto! Para Sdl me viene bien. ;)
Saludos y gracias! 


Título: Re: Duda con temporizador en C++
Publicado por: anonimo12121 en 7 Julio 2013, 02:21 am
http://c.conclase.net/librerias/index.php?ansilib=time#inicio aquí tienes !
Espero que te sirva, creo que es mejor que usar una libreria que puede que incluya cosas no necesaría digo yo.



La verdad es que no entiendo muy bien todo eso de DWORD, LPVOID y lpParam. ¿Qué significan exactamente?
Creo que son typedef de VS en plan;

typedef unsigned int Uint
Uint x=5;//Bien
Uint x= -1; Mal solo acepta positivos.


Título: Re: Duda con temporizador en C++
Publicado por: rir3760 en 7 Julio 2013, 04:55 am
typedef unsigned int Uint
Uint x=5;//Bien
Uint x= -1; Mal solo acepta positivos.
No. La ultima asignación es valida (operaciones de ese tipo pueden causar un verdadero dolor de cabeza).

Ello porque si un valor esta fuera del rango valido (tipo entero sin signo) a este se le suma (o resta, dependiendo del caso) MAX + 1 hasta que este en el rango valido.

Por cierto el ejemplo que pones es la forma usual para calcular el valor máximo sin tener que utilizar el encabezado <limits.h>. Un ejemplo:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <limits.h>
  4.  
  5. int main(void)
  6. {
  7.   /* Imprime el valor maximo para el tipo unsigned int */
  8.   printf("%u\n", (unsigned) -1);
  9.   printf("%u\n", UINT_MAX);
  10.  
  11.   /* Imprime el valor maximo para el tipo unsigned long */
  12.   printf("%lu\n", (unsigned long) -1);
  13.   printf("%lu\n", ULONG_MAX);
  14.  
  15.   return EXIT_SUCCESS;
  16. }

Otro escenario problemático son las expresiones donde se utilizan valores de tipo signed y unsigned. Por ejemplo este programa en C:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main(void)
  5. {
  6.   int a = -1;
  7.   int b = 0;
  8.   unsigned x = 0;
  9.  
  10.   printf("%d < %d  ? %s\n", a, b, a < b ? "Si" : "No");
  11.   printf("%d < %uU ? %s\n", a, x, a < x ? "Si" : "No");
  12.  
  13.   return EXIT_SUCCESS;
  14. }

Genera la salida:
Código:
-1 < 0  ? Si
-1 < 0U ? No

Ello porque los operandos de un operador binario deben ser del mismo tipo, en este caso el valor -1 de tipo signed int se convierte automáticamente al tipo unsigned int resultando en el valor mencionado (el máximo) y solo entonces se realiza la comparación.

Y si bien un compilador en modo estricto puede generar un mensaje de advertencia al compilar ese programa (o uno similar) ello no esta garantizado (y a veces uno las desactiva al saber que son inocuas).

Un saludo


Título: Re: Duda con temporizador en C++
Publicado por: SrCooper en 7 Julio 2013, 12:29 pm
Si prefieres un for aquí lo tienes a lo ansi. XD

Está bien el código, pero como dice amchacon, hace exactamente lo mismo que un rest(). Y el rest es completamente inútil en un videojuego, porque para todo el bucle y es imposible jugar :D

Al final me he decantado por aprender hilos y poner el rest en segundo plano.

Un saludo