Forum > Games

Problems with abstract class in allegro5

(1/2) > >>

zelda16bit:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---     unit Upadre;         {$mode objfpc}{$H+}         interface         uses      Allegro5,Generics.Collections;         type      Tpadre = class        strict private          padre: Tpadre;          lista: specialize TObjectList<Tpadre>;        public          constructor Create();          procedure pintar();virtual;abstract;          procedure actualizar();          destructor Destroy(); override;      end;         implementation           constructor Tpadre.Create();      begin        lista := specialize TObjectList<Tpadre>.Create(True);        lista.Add(Self);      end;           procedure Tpadre.actualizar();      begin        for padre in lista do begin          padre.pintar();        end;      end;           destructor Tpadre.Destroy();      begin        lista.Free();        lista := nil;      end;         end. 

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Udisparo; {$Mode objfpc} {$H+} interface uses  Allegro5,Upadre; type//prototipo clase disparo-----------------------------  Tdisparo = class(Tpadre)    strict private      imagen: ALLEGRO_BITMAPptr;      x,y: real;    public      constructor Create(x1,y1: real);      procedure pintar();      procedure mover();      procedure eliminar();      destructor Destroy(); override;  end; //fin prototipo clase disparo------------------------- implementation //implementacion clase disparo-----------------------  constructor Tdisparo.Create(x1,y1: real);  begin    inherited Create();    imagen := al_load_bitmap('estrella.png');    x := x1;    y := y1;  end;   procedure Tdisparo.pintar();  begin    mover();    eliminar();    al_draw_bitmap(imagen,x,y,0);  end;   procedure Tdisparo.mover();  begin    y := y - 5;  end;   procedure Tdisparo.eliminar();  begin    if(y < 64) then    begin      self.destruir();    end;  end;   destructor Tdisparo.Destroy();  begin    al_destroy_bitmap(imagen);    imagen := nil;    inherited;  end;//fin implementacion clase disparo------------------- end.  

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$mode objfpc} {$H+}program alegro10; (*  allegro5 -> biblioteca alegro  al5image -> biblioteca para imagenes  Generics.Collections -> para usar listas*) uses  allegro5,al5image,Udisparo,Upadre; //prototipo clase jugador-----------------------------type  Tjugador = class    strict private      imagen: ALLEGRO_BITMAPptr;      estado_de_teclas: ALLEGRO_KEYBOARD_STATE;      x,y: real;      contador: integer;      disparo: Tdisparo;    public      constructor Create();      procedure pintar();      procedure mover();      procedure disparar();      destructor Destroy(); override;  end;//fin prototipo clase jugador------------------------- //implementacion clase jugador------------------------  constructor Tjugador.Create();  begin    imagen := al_load_bitmap('nave.png');    x := 320;    y := 240;  end;   procedure Tjugador.pintar();  begin    mover();    disparar();    //pintamos imagen(imagen,x,y,voltear)    al_draw_bitmap(imagen,x,y,0);  end;   procedure Tjugador.mover();  begin    al_get_keyboard_state(estado_de_teclas);    if(al_key_down(estado_de_teclas,ALLEGRO_KEY_LEFT)) then    begin      x := x - 5;    end    else if(al_key_down(estado_de_teclas,ALLEGRO_KEY_RIGHT)) then    begin      x := x + 5;    end;     if(al_key_down(estado_de_teclas,ALLEGRO_KEY_UP)) then    begin      y := y - 5;    end    else if(al_key_down(estado_de_teclas,ALLEGRO_KEY_DOWN)) then    begin      y := y + 5;    end;  end;   procedure Tjugador.disparar();  begin    al_get_keyboard_state(estado_de_teclas);    contador := contador + 1;    if (al_key_down(estado_de_teclas,ALLEGRO_KEY_Z)) and (contador > 10) then    begin      //crear disparo      disparo := Tdisparo.Create(x,y);      contador := 0;    end;  end;   destructor Tjugador.Destroy();  begin    al_destroy_bitmap(imagen);    imagen := nil;    disparo.Free;    disparo := nil;  end;//fin implementacion clase jugador------------------- var  ventana: ALLEGRO_DISPLAYptr = nil;  evento: ALLEGRO_EVENT;  cola_de_eventos: ALLEGRO_EVENT_QUEUEptr = nil;  tiempo: ALLEGRO_TIMERptr = nil;  ejecutar: Boolean;  jugador: Tjugador;  //padre: Tpadre; begin  //iniciar allegro  al_init();  //instalar teclado  al_install_keyboard();  //iniciar imagen  al_init_image_addon();   //configurar ventana en modo ventana  al_set_new_display_flags(ALLEGRO_WINDOWED);  //crear ventana(ancho,alto)  ventana := al_create_display(640,480);   //ocultar raton  al_hide_mouse_cursor(ventana);   //crear cola de eventos  cola_de_eventos := al_create_event_queue();   //crear tiempo para fps  tiempo := al_create_timer(1/60);   //registrar eventos  al_register_event_source(cola_de_eventos,al_get_keyboard_event_source());  al_register_event_source(cola_de_eventos,al_get_display_event_source(ventana));  al_register_event_source(cola_de_eventos,al_get_timer_event_source(tiempo));   //inicio de variables  ejecutar := true;  jugador := Tjugador.Create();  //padre := Tpadre.Create();   //iniciamos el tiempo  al_start_timer(tiempo);  while (ejecutar = true) do  begin     //esperamos a la cola de eventos    al_wait_for_event(cola_de_eventos,@evento);    case evento.ftype of      //manejo de fps      ALLEGRO_EVENT_TIMER: begin        //limpiar pantalla con un color cualquiera        al_clear_to_color(al_map_rgb(0,0,160));         jugador.pintar();        Tpadre.actualizar();         //actualizar pantalla        al_flip_display();      end;      //si pulso escape salgo del bucle      ALLEGRO_EVENT_KEY_DOWN: begin        if (evento.keyboard.keycode = ALLEGRO_KEY_ESCAPE) then        begin          ejecutar := false;        end;      end;    end; //fin case   end; //fin bucle while   al_destroy_display(ventana); //destruir ventana  ventana := nil;  al_destroy_event_queue(cola_de_eventos); //destruir cola  cola_de_eventos := nil;  al_destroy_timer(tiempo); //destruir tiempo  tiempo := nil;  al_uninstall_keyboard(); //desinstalar teclado  jugador.Free(); //liberar jugador  jugador := nil;  //padre.Free;  //padre := nil; end. //fin programa  
I have created the abstract method paint to use it in the child classes that inherit from this, in the parent class I will not use it only in the daughters but in the update method I call it because this method will be responsible for updating all the methods to paint of all the child classes, however the compiler tells me that it can not be used and gives me an error.

There are also problems with memory freeing,I leave the file with the complete code, Allegro 5 is needed to compile.

Eugene Loza:

--- Quote ---however the compiler tells me that it can not be used and gives me an error
--- End quote ---

If I understand your code correctly, compiler is correct about it. While FPC will indeed let you instantiate a class with an abstract method and it should be ok if you don't use the abstract method, in your case you:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---lista.Add(Self); and then


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- for padre in lista do begin  padre.pintar();end;
I.e. the Self class is in the list and you call an abstract `pintar` method on it, which is not allowed. If you really need to make something like that - just don't make `pintar` abstract, just an empty method:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure Tpadre.pintar;beginend;
and then override it in children to make something more useful there.

zelda16bit:
I have added all the code from my example, the problem with the abstract method has been solved with what you have told me, but another problem has arisen. The parent class update method when I call it from the main file I get a generic.collection error.

Ñuño_Martínez:
I've downloaded and tested your program and I have no problem at all.

Debian GNU/Linux 11 + Lazarus 2.2.4 + FPC 3.2.2 + Allegro.pas 5.2.β.1.

zelda16bit:
That's because I have commented this line //Tpadre.update(); In the while loop, if you do not comment you will see that the problems begin. You will also see that pressing z does not shoot anything, uncomment and you will see

Navigation

[0] Message Index

[#] Next page

Go to full version