Recent

Author Topic: Como destruir un objeto del juego en allegro5  (Read 15339 times)

zelda16bit

  • Full Member
  • ***
  • Posts: 118
Como destruir un objeto del juego en allegro5
« on: December 28, 2021, 05:41:49 pm »
Hola. :)

Estaba mirando la documentacion de allegro5 y no veo ni funciones para destruir objetos ni para colisiones(no entiendo porque),entonces estoy utilizando una lista de objetos con generic.collection.

No he usado esto nunca en ningun caso practico y por ahora me funciona lo que estoy haciendo,pero hay algo que no funciona bien.Tengo activada la opcion de heaptrc que se lo vi usar a ÑUÑO en el tutorial de allegro y es para saber si se estan liberando correctamente los objetos creo,pero hay bloques de memoria que no se estan liberando y no se donde esta el error.

Voy a poner el codigo por si alguien quiere mirarlo,hay dos clases,una del disparo y otra del jugador donde se dispara y se añade el disparo a la lista.

Code: Pascal  [Select][+][-]
  1. {$mode objfpc} {$H+}
  2. program alegro10;
  3.  
  4. (*
  5.   allegro5 -> biblioteca alegro
  6.   al5image -> biblioteca para imagenes
  7.   Generics.Collections -> para usar listas
  8. *)
  9.  
  10. uses
  11.   allegro5,al5image,Udisparo;
  12.  
  13. var lista_disparo: Tlista_disparo;
  14. //prototipo clase jugador-----------------------------
  15. type
  16.   Tjugador = class
  17.     strict private
  18.       imagen: ALLEGRO_BITMAPptr;
  19.       estado_de_teclas: ALLEGRO_KEYBOARD_STATE;
  20.       x,y: real;
  21.       contador: integer;
  22.       //lista_disparo: Tlista_disparo;
  23.       disparo,d: Tdisparo;
  24.     public
  25.       constructor Create();
  26.       procedure pintar();
  27.       procedure mover();
  28.       procedure disparar();
  29.       destructor Destroy(); override;
  30.   end;
  31. //fin prototipo clase jugador-------------------------
  32.  
  33. //implementacion clase jugador------------------------
  34.   constructor Tjugador.Create();
  35.   begin
  36.     imagen := al_load_bitmap('nave.png');
  37.     x := 320;
  38.     y := 240;
  39.     lista_disparo := Tlista_disparo.Create(true);
  40.   end;
  41.  
  42.   procedure Tjugador.pintar();
  43.   begin
  44.     mover();
  45.     disparar();
  46.     //pintamos imagen(imagen,x,y,voltear)
  47.     al_draw_bitmap(imagen,x,y,0);
  48.     //recorrer lista disparo
  49.     for d in lista_disparo do
  50.     begin
  51.       d.pintar();
  52.       if(d.y < 64) then
  53.         //eliminar disparo
  54.         lista_disparo.Extract(d);
  55.     end;
  56.   end;
  57.  
  58.   procedure Tjugador.mover();
  59.   begin
  60.     al_get_keyboard_state(estado_de_teclas);
  61.     if(al_key_down(estado_de_teclas,ALLEGRO_KEY_LEFT)) then
  62.     begin
  63.       x := x - 5;
  64.     end
  65.     else if(al_key_down(estado_de_teclas,ALLEGRO_KEY_RIGHT)) then
  66.     begin
  67.       x := x + 5;
  68.     end;
  69.  
  70.     if(al_key_down(estado_de_teclas,ALLEGRO_KEY_UP)) then
  71.     begin
  72.       y := y - 5;
  73.     end
  74.     else if(al_key_down(estado_de_teclas,ALLEGRO_KEY_DOWN)) then
  75.     begin
  76.       y := y + 5;
  77.     end;
  78.   end;
  79.  
  80.   procedure Tjugador.disparar();
  81.   begin
  82.     al_get_keyboard_state(estado_de_teclas);
  83.     contador := contador + 1;
  84.     if (al_key_down(estado_de_teclas,ALLEGRO_KEY_Z)) and (contador > 10) then
  85.     begin
  86.       //crear disparo y añadir a la lista
  87.       disparo := Tdisparo.Create(x+24,y);
  88.       lista_disparo.Add(disparo);
  89.       contador := 0;
  90.     end;
  91.   end;
  92.  
  93.   destructor Tjugador.Destroy();
  94.   begin
  95.     al_destroy_bitmap(imagen);
  96.     imagen := nil;
  97.     lista_disparo.Free();
  98.     lista_disparo := nil;
  99.   end;
  100. //fin implementacion clase jugador-------------------
  101.  
  102. var
  103.   ventana: ALLEGRO_DISPLAYptr = nil;
  104.   evento: ALLEGRO_EVENT;
  105.   cola_de_eventos: ALLEGRO_EVENT_QUEUEptr = nil;
  106.   tiempo: ALLEGRO_TIMERptr = nil;
  107.   ejecutar: Boolean;
  108.   jugador: Tjugador;
  109.  
  110. begin
  111.   //iniciar allegro
  112.   al_init();
  113.   //instalar teclado
  114.   al_install_keyboard();
  115.   //iniciar imagen
  116.   al_init_image_addon();
  117.  
  118.   //configurar ventana en modo ventana
  119.   al_set_new_display_flags(ALLEGRO_WINDOWED);
  120.   //crear ventana(ancho,alto)
  121.   ventana := al_create_display(640,480);
  122.  
  123.   //ocultar raton
  124.   al_hide_mouse_cursor(ventana);
  125.  
  126.   //crear cola de eventos
  127.   cola_de_eventos := al_create_event_queue();
  128.  
  129.   //crear tiempo para fps
  130.   tiempo := al_create_timer(1/60);
  131.  
  132.   //registrar eventos
  133.   al_register_event_source(cola_de_eventos,al_get_keyboard_event_source());
  134.   al_register_event_source(cola_de_eventos,al_get_display_event_source(ventana));
  135.   al_register_event_source(cola_de_eventos,al_get_timer_event_source(tiempo));
  136.  
  137.   //inicio de variables
  138.   ejecutar := true;
  139.   jugador := Tjugador.Create();
  140.  
  141.   //iniciamos el tiempo
  142.   al_start_timer(tiempo);
  143.   while (ejecutar = true) do
  144.   begin
  145.  
  146.     //esperamos a la cola de eventos
  147.     al_wait_for_event(cola_de_eventos,@evento);
  148.     case evento.ftype of
  149.       //manejo de fps
  150.       ALLEGRO_EVENT_TIMER: begin
  151.         //limpiar pantalla con un color cualquiera
  152.         al_clear_to_color(al_map_rgb(0,0,160));
  153.  
  154.         jugador.pintar();
  155.  
  156.         //actualizar pantalla
  157.         al_flip_display();
  158.       end;
  159.       //si pulso escape salgo del bucle
  160.       ALLEGRO_EVENT_KEY_DOWN: begin
  161.         if (evento.keyboard.keycode = ALLEGRO_KEY_ESCAPE) then
  162.         begin
  163.           ejecutar := false;
  164.         end;
  165.       end;
  166.     end; //fin case
  167.  
  168.   end; //fin bucle while
  169.  
  170.   al_destroy_display(ventana); //destruir ventana
  171.   ventana := nil;
  172.   al_destroy_event_queue(cola_de_eventos); //destruir cola
  173.   cola_de_eventos := nil;
  174.   al_destroy_timer(tiempo); //destruir tiempo
  175.   tiempo := nil;
  176.   al_uninstall_keyboard(); //desinstalar teclado
  177.   jugador.Free(); //liberar jugador
  178.   jugador := nil;
  179.  
  180. end. //fin programa
  181.  

Code: Pascal  [Select][+][-]
  1. unit Udisparo;
  2.  
  3. {$Mode objfpc} {$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Allegro5,Generics.Collections;
  9.  
  10. type
  11. //prototipo clase disparo-----------------------------
  12.   Tdisparo = class
  13.     strict private
  14.       imagen: ALLEGRO_BITMAPptr;
  15.       //x,y: real;
  16.     public
  17.       x,y: real;
  18.       constructor Create(x1,y1: real);
  19.       procedure pintar();
  20.       procedure mover();
  21.       destructor Destroy(); override;
  22.   end;
  23.  
  24.   Tlista_disparo = specialize TObjectList<Tdisparo>;
  25. //fin prototipo clase disparo-------------------------
  26.  
  27. implementation
  28.  
  29. //implementacion clase disparo-----------------------
  30.   constructor Tdisparo.Create(x1,y1: real);
  31.   begin
  32.     imagen := al_load_bitmap('estrella.png');
  33.     x := x1;
  34.     y := y1;
  35.   end;
  36.  
  37.   procedure Tdisparo.pintar();
  38.   begin
  39.     mover();
  40.     al_draw_bitmap(imagen,x,y,0);
  41.   end;
  42.  
  43.   procedure Tdisparo.mover();
  44.   begin
  45.     y := y - 5;
  46.   end;
  47.  
  48.   destructor Tdisparo.Destroy();
  49.   begin
  50.     al_destroy_bitmap(imagen);
  51.     imagen := nil;
  52.   end;
  53. //fin implementacion clase disparo-------------------
  54.  
  55. end.
  56.  
  57.  

Por cierto ÑUÑO,me tienes abandonado.No paro de hacer preguntas sobre allegro y no veo tus respuesta,reconozco que eso me desmotiva un poco.  :'(

« Last Edit: December 31, 2021, 07:09:39 pm by zelda16bit »

mosquito

  • Full Member
  • ***
  • Posts: 141
Re: Como destruir un objeto del juego en allegro5
« Reply #1 on: December 28, 2021, 07:13:41 pm »
Para colisiones básicas uso la unidad types:  https://www.freepascal.org/docs-html/rtl/types/index-5.html

zelda16bit

  • Full Member
  • ***
  • Posts: 118
Re: Como destruir un objeto del juego en allegro5
« Reply #2 on: December 29, 2021, 05:13:36 pm »
Para colisiones básicas uso la unidad types:  https://www.freepascal.org/docs-html/rtl/types/index-5.html

Gracias por el enlace,aunque no hay ejemplos para saber como usar esas funciones.

Ñuño_Martínez

  • Hero Member
  • *****
  • Posts: 1186
    • Burdjia
Re: Como destruir un objeto del juego en allegro5
« Reply #3 on: December 29, 2021, 09:54:58 pm »
Hola. :)

Estaba mirando la documentacion de allegro5 y no veo ni funciones para destruir objetos ni para colisiones(no entiendo porque),entonces estoy utilizando una lista de objetos con generic.collection.
Allegro tiene funciones para destruir los objetos que crea.  Ten en cuenta que Allegro está escrito en C y que Allegro.pas es sólo la "traducción" de las cabeceras, por lo que apenas contiene código específico para Pascal.

Por otro lado, lo de las colisiones.  Allegro no es un motor, como Castle Engine, GameMaker, Godot o Unity, por eso no incluye funciones de colisión.  La gestión de colisiones depende de muchos factores.  Normalmente suelen calcularse las colisiones entre dos rectángulos.

Te dejo un enlace al método Collide que implementé para mi motor Mingro (la versión vieja, aunque la próxima será prácticamente la misma).  Creo que es autoexplicativa, pero si necesitas ayuda, dibuja dos rectángulos en un papel en diferentes situaciones (colisión, no colisión, dentro de, fuera...) y seguro que te ayuda.

Por cierto ÑUÑO,me tienes abandonado.No paro de hacer preguntas sobre allegro y no veo tus respuesta,reconozco que eso me desmotiva un poco.  :'(

Ya lo siento, pero por mi trabajo apenas tengo tiempo libre.  Pero ya ves que otras personas también ayudan, afortunadamente. :)
Are you interested in game programming? Join the Pascal Game Development community!
Also visit the Game Development Portal

zelda16bit

  • Full Member
  • ***
  • Posts: 118
Re: Como destruir un objeto del juego en allegro5
« Reply #4 on: December 30, 2021, 05:01:15 pm »
Hola Ñuño.

No encuentro esas funciones que comentas para destruir objetos,si puedes decirme cuales son y poner algun ejemplo de ello,aunque tambien me vendria bien que me dijeras como solucionar el problema que tengo con las listas de objetos en el ejemplo que he puesto en este hilo,no consigo ver donde estan los errores.

BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
Re: Como destruir un objeto del juego en allegro5
« Reply #5 on: December 31, 2021, 04:17:34 pm »
Hola Zelda16bit. Veo que en tu programa creas objetos (clases) propias como TJugarodor y TDisparo.

Asegurate que tu objeto, dentro del método Desrtroy del mismo, borra todo lo que haya creado.

Viendo tú código, no parece que hayas dejado nada sin borrar. Manda una captura del resultado de heaptrc  a ver que dice.

Por otra parte, si envias tú código, y tiene varias unidades, es más cómodo que uses el menú publicar proyecto, dentro del menú proyecto. Con esto podrás crear un archivo comprimido con todo lo que necesita tú programa y subirlo al foro.

Saludos


BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
Re: Como destruir un objeto del juego en allegro5
« Reply #6 on: December 31, 2021, 04:20:48 pm »
  Ya lo siento, pero por mi trabajo apenas tengo tiempo libre.  Pero ya ves que otras personas también ayudan, afortunadamente. :)
A ver si entre todos levantamos una comunidad de videjuegos y lazarus/fpc en castellano
Saludos

zelda16bit

  • Full Member
  • ***
  • Posts: 118
Re: Como destruir un objeto del juego en allegro5
« Reply #7 on: December 31, 2021, 05:39:51 pm »
Hola Zelda16bit. Veo que en tu programa creas objetos (clases) propias como TJugarodor y TDisparo.

Asegurate que tu objeto, dentro del método Desrtroy del mismo, borra todo lo que haya creado.

Viendo tú código, no parece que hayas dejado nada sin borrar. Manda una captura del resultado de heaptrc  a ver que dice.

Por otra parte, si envias tú código, y tiene varias unidades, es más cómodo que uses el menú publicar proyecto, dentro del menú proyecto. Con esto podrás crear un archivo comprimido con todo lo que necesita tú programa y subirlo al foro.

Saludos

He puesto la captura y he subido el ejemplo comprimido,pero le faltan los dll de allegro porque no me permite subir mas de 500 kb,lo de publicar proyecto no se donde esta.

zelda16bit

  • Full Member
  • ***
  • Posts: 118
Re: Como destruir un objeto del juego en allegro5
« Reply #8 on: December 31, 2021, 05:45:12 pm »
A ver si entre todos levantamos una comunidad de videjuegos y lazarus/fpc en castellano
Saludos

Lo que necesita allegro/pascal son unos tutoriales sencillos que te enseñen a programar distintos tipos de juegos,o tutoriales cortos que te enseñen las cosas necesarias para programar tus propios juegos sin centrarte en ningun estilo en particular,si no es imposible avanzar. Un saludo y feliz año a todos

BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
Re: Como destruir un objeto del juego en allegro5
« Reply #9 on: December 31, 2021, 08:18:11 pm »
Hola zelda16bit, fíjate en la imagen que adjunto. Indica que la fuga de memoria se produce en la línea 87 del archivo allegro10.lpr. Si observas esa línea en tú codigo podemos encontrar
Code: [Select]
disparo := Tdisparo.Create(x+24,y);

La línea siguiente, indica que fue llamada esa parte del progama, desde la línea 45.
También veo que las líneas siguientes son iguales, lo que indica que has creado más de una vez ese objeto (el de la línea 87) y no lo has destruido.
 
No he trabajado con listas genéricas, pero si funcionan igual que las listas hechas con TCollection, después de añadir el objeto a la lista ya puedes borrarlo.
Yo modificaría el código y lo dejaría así:
Code: [Select]
  if (al_key_down(estado_de_teclas,ALLEGRO_KEY_Z)) and (contador > 10) then
    begin
      //crear disparo y añadir a la lista
      disparo := Tdisparo.Create(x+24,y);
      lista_disparo.Add(disparo);
      contador := 0;
      FreeAndNil(disparo); //Borrar el objeto
    end;

Gracias por empaquetar el código. Si puedo lo prueba más tarde a ver si se soluciona el problema de la fuga de memoria.

Saludos
/BlueIcaro

BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
Re: Como destruir un objeto del juego en allegro5
« Reply #10 on: December 31, 2021, 08:40:07 pm »
A ver si entre todos levantamos una comunidad de videjuegos y lazarus/fpc en castellano
Saludos

Lo que necesita allegro/pascal son unos tutoriales sencillos que te enseñen a programar distintos tipos de juegos,o tutoriales cortos que te enseñen las cosas necesarias para programar tus propios juegos sin centrarte en ningun estilo en particular,si no es imposible avanzar. Un saludo y feliz año a todos

Es una buena idea, desde que vi el vídeo Nuño, estoy pensando en escribir algo de lo vaya aprendiendo de Allegro, que por ahora no es mucho. Pero necesito sacar tiempo aprender Allegro luego para escribir :-[

BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
Re: Como destruir un objeto del juego en allegro5
« Reply #11 on: December 31, 2021, 09:18:16 pm »
Quote
No he trabajado con listas genéricas, pero si funcionan igual que las listas hechas con TCollection, después de añadir el objeto a la lista ya puedes borrarlo.
Yo modificaría el código y lo dejaría así:
Code: [Select]

  if (al_key_down(estado_de_teclas,ALLEGRO_KEY_Z)) and (contador > 10) then
    begin
      //crear disparo y añadir a la lista
      disparo := Tdisparo.Create(x+24,y);
      lista_disparo.Add(disparo);
      contador := 0;
      FreeAndNil(disparo); //Borrar el objeto
    end;


Gracias por empaquetar el código. Si puedo lo prueba más tarde a ver si se soluciona el problema de la fuga de memoria.
Hola, lo que puse encima no funcionada, da error al ejecutar. Pero el problema de la fuga de memoria sigue siendo que creas clases TDisparo y no las borras.
Saludos
/BLueIcaro

zelda16bit

  • Full Member
  • ***
  • Posts: 118
Re: Como destruir un objeto del juego en allegro5
« Reply #12 on: January 01, 2022, 10:55:40 am »
Es una buena idea, desde que vi el vídeo Nuño, estoy pensando en escribir algo de lo vaya aprendiendo de Allegro, que por ahora no es mucho. Pero necesito sacar tiempo aprender Allegro luego para escribir :-[

No hace falta que sea allegro,puede ser de cualquier libreria grafica que se sepa usar.Lo importante es enseñar los mecanismos necesarios para programar juegos con freepascal,una vez se sepa esto se puede trasladar facilmente a allegro.
« Last Edit: January 01, 2022, 10:58:09 am by zelda16bit »

zelda16bit

  • Full Member
  • ***
  • Posts: 118
Re: Como destruir un objeto del juego en allegro5
« Reply #13 on: January 01, 2022, 11:03:53 am »
Quote
No he trabajado con listas genéricas, pero si funcionan igual que las listas hechas con TCollection, después de añadir el objeto a la lista ya puedes borrarlo.
Yo modificaría el código y lo dejaría así:
Code: [Select]

  if (al_key_down(estado_de_teclas,ALLEGRO_KEY_Z)) and (contador > 10) then
    begin
      //crear disparo y añadir a la lista
      disparo := Tdisparo.Create(x+24,y);
      lista_disparo.Add(disparo);
      contador := 0;
      FreeAndNil(disparo); //Borrar el objeto
    end;


Gracias por empaquetar el código. Si puedo lo prueba más tarde a ver si se soluciona el problema de la fuga de memoria.
Hola, lo que puse encima no funcionada, da error al ejecutar. Pero el problema de la fuga de memoria sigue siendo que creas clases TDisparo y no las borras.
Saludos
/BLueIcaro

Despues de ver esto me puse a liberar el codigo en distintas partes pero me da error.En el metodo pintar de la clase jugador estoy extrayendo la lista para eliminar el objeto y hay deberia de poderse liberar la memoria pero da error y en otras partes igual,es un lio esto de la liberacion de memoria.

Las listas genericas la estoy usando porque se recomendaba en la pagina de castle engine pero me da igual cual se use,mientras funcione.

BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
Re: Como destruir un objeto del juego en allegro5
« Reply #14 on: January 01, 2022, 04:41:31 pm »
Hola Zelda16bit, hice una pequeña aproximación de como sería hacer listas usando TCollection.
Te adjunto el programa. Échale un vistazo.

Saludos

/BlueIcaro

 

TinyPortal © 2005-2018