• Martes 14 de Mayo de 2024, 11:30

Autor Tema:  Les Pido Ayuda  (Leído 2446 veces)

Renatus

  • Miembro activo
  • **
  • Mensajes: 27
    • Ver Perfil
Les Pido Ayuda
« en: Domingo 11 de Septiembre de 2005, 20:37 »
0
Hola a todos  :lol: !!!
Despues de tanto tiempo, vuelvo a las andadas con alguna pregunta que, me gustaría pudieran responderme:

Estoy diseñando un rpg con tiles bajo C++ y Allegro. El mundo con tiles, así como los metodos de pintado y de armado del mundo ya están hechos pero donde
encuentro problemas es cuando planteo la inclusion de objetos moviles dentro del mundo.

Necesito almacenar la totalidad de los objetos moviles que apareceran dentro
del mundo en una estructura.
El problema es que quisiera codificar a cada objeto como una clase diferente.
Hace un tiempo me habían recomendado que usara una lista enlazada pero
hasta donde yo sé, una lista enlazada solo pude almacenar objetos de un mismo
tipo( O sea una misma clase).

La solucion sería tener una lista enlazada para cada tipo de objeto diferente?

Por ejemplo tener una lista particular para los objetos de tipo "televisor", otra para los objetos de tipo "personajes", etc.
O existe alguna manera de crear una lista enlazada que soporte objetos de tipo diferente?


Muchas gracias por su ayuda.
 :D

Renatus
Es cosa mía o el modo 320x240x256 conserva todavía algo de magia?

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Re: Les Pido Ayuda
« Respuesta #1 en: Lunes 12 de Septiembre de 2005, 05:19 »
0
NO,
aunque siempre hay muchas formas de llegar al mismo punto.

Proi si has hecho las cosas de la manera correcta, todos los personasjes u objetos moviles deben estar heredando de un mismo objeto comun, asi que el array es de este objeto comun del cual heredan.

O bien puede que todos esten implementando una interfaz  comun , asi que el  array puede ser de objetos que tengan esa interfaz.
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io

Renatus

  • Miembro activo
  • **
  • Mensajes: 27
    • Ver Perfil
Re: Les Pido Ayuda
« Respuesta #2 en: Miércoles 14 de Septiembre de 2005, 05:07 »
0
Muchas gracias JuanK  :lol: .
La verdad es que no me ha quedado clara tu recomendación con respecto
a la lista enlazada de clases heredadas.

La idea de almacenar todos los objetos moviles existentes de un escenario
surje de la necesidad de darle a cada uno de ellos la oportunidad, uno a uno
por vez, de que procesen algunos metodos propios de actualizacion, y a la vez de pintado en el escenario.
Como el juego no sabe exactamente cuantos objetos existen en ese momento
en el escenario, consulta la lista para ver cuales y cuantos son.
De esta manera, se invoca un metodo comun de cada objeto, para darle
a cada objeto la posibilidad de que se actualize y se pinte en pantalla.

Lo que no llego a entender acerca de esto es:

Por ejemplo, si construyo una lista enlazada para objetos de un determinado tipo,
no podría introducir en esa lista objetos que estén construidos a base de ese tipo
porque el tipo nuevo que surje pasaría a ser otro diferente. O sí  :huh: ?

Muchas gracias por responder, de verdad que estoy bastante confundido con respecto a este asunto.
 :D
Es cosa mía o el modo 320x240x256 conserva todavía algo de magia?

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Re: Les Pido Ayuda
« Respuesta #3 en: Miércoles 14 de Septiembre de 2005, 05:20 »
0
Bien, en efecto si una clase ha 'nacido' (heredado) a partir de otra, los objetos que se instancien de esta bien pueden ser 'casteados' como si fueran de la clase padre.

Auque esto puede njo ser tan real en todos los lenguajes, pero en lenguajes como C++, Java y C#, esto es totalment cierto.

Para tu caso aunque la clase televisor sea diferente de la case radio, en el caso de que ambos hayan sido creados derivando de la clase Actor, ambos pueden ser parte de un array de objetos tipo actor.

Creo que has entendido bien.
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io

Neko-sama

  • Miembro activo
  • **
  • Mensajes: 99
    • Ver Perfil
Re: Les Pido Ayuda
« Respuesta #4 en: Miércoles 14 de Septiembre de 2005, 06:23 »
0
debieras poder tener un arreglo dinamico de objetos de un tipo por ejemplo alguna interfaz.

osea... haces que todos tus objetos... cualquiera sean hereden de esta interfaz... de esa forma creas el arreglo de tipo interfaz... asi sabes que todos tienen el metodo que necesitas...    ese es uno de los grandes usos que tiene usar una interfaz

................Emergencia
...............*SuenaSirena
......................||
.......... -----------------------
......... ||..........................||
......... ||..........................||
.......Auto.....................Camion


De esa forma Auto y Cambion van a heredar el metodo SuenaSirena y ademas son de un tipo en comun, entonces puedes hacer tu arreglo de tipo Emergencia y todo lo que agregues a ese arreglo no va a tener problemas porque herendan de Emergencia y si vas a llamar un metodo en comun... ese es SuenaSirena...

así no importa los tipos que sean estos porque en si todos tienen el mismo origen.

osea... no necesita ser una lista enlazada... solo un arreglo de punteros de tipo de alguna Interfaz...

Renatus

  • Miembro activo
  • **
  • Mensajes: 27
    • Ver Perfil
Re: Les Pido Ayuda
« Respuesta #5 en: Miércoles 14 de Septiembre de 2005, 07:37 »
0
He visto la luz, muchachos  ;)
Muchas gracias JuanK y Neko-sama.
No sabía que podían hacerse arreglos de esa manera con clases heredadas.
Me han enseñado algo que no sabía. Me servirá de mucho.

De nuevo gracias a ustedes y nos mantenemos en contacto.

Renatus  :D
Es cosa mía o el modo 320x240x256 conserva todavía algo de magia?

Diodo

  • Moderador
  • ******
  • Mensajes: 658
    • Ver Perfil
    • http://www.solocodigo.com
Re: Les Pido Ayuda
« Respuesta #6 en: Miércoles 14 de Septiembre de 2005, 08:20 »
0
Hola

Aca te dejo un pequeño codigo que hicimos para construir un planetario en opengl, usando herencia y polimorfismo

Código: Text
  1.  
  2. class ObjetoCeleste;
  3.  
  4. //Clase contenedora de Objetos Celestes. Utiliza memoria estática
  5. //por lo que como máximo almacenará hasta 100
  6. class ListaObjetos
  7. {
  8.   ObjetoCeleste *lista[100];
  9.   int num;
  10. public:
  11.   ListaObjetos(){num=0;}
  12.   ObjetoCeleste * operator[](int i)
  13.     {
  14.     if((i<num)&&(i>-1))return lista[i];
  15.     else return NULL;
  16.     }
  17.   bool AgregarObjeto(ObjetoCeleste *obj)
  18.     {
  19.     if(num<100){lista[num++]=obj;return true;}
  20.     else return false;
  21.     }
  22.   void Itera();
  23.   void Pinta();
  24.   int GetNum(){return num;}
  25.  
  26. };
  27.  
  28. class ObjetoCeleste
  29. {
  30. protected:
  31.   double posicion[3];
  32.   double velocidad[3];
  33.   int tipo;
  34. public:
  35.  
  36.   ObjetoCeleste(double x, double y, double z,double vx,double vy,double vz)
  37.     {
  38.     posicion[0]=x;posicion[1]=y;posicion[2]=z;
  39.     velocidad[0]=vx;velocidad[1]=vy;velocidad[2]=vz;
  40.     }
  41.   virtual void Pintar(){}
  42.   virtual void Itera(ListaObjetos &lista)
  43.     {
  44.     for(int i=0;i<3;i++)posicion[i]+=velocidad[i];
  45.     }
  46.   double operator -(ObjetoCeleste &obj)
  47.     {
  48.     double dist=0;
  49.     for(int i=0;i<3;i++)
  50.       dist+=((posicion[i]-obj.posicion[i])*(posicion[i]-obj.posicion[i]));
  51.     return sqrt(dist);
  52.     }
  53.   void PrePintado()
  54.     {
  55.     glPushMatrix();
  56.     glTranslated(posicion[0],posicion[1],posicion[2]);
  57.     }
  58.   void PostPintado(){glPopMatrix();}
  59. };
  60.  
  61.  
  62. class Planeta:public ObjetoCeleste
  63. {
  64. protected:
  65.   double Masa;
  66.   double Radio;
  67.   float Color[3];
  68. public:
  69.   Planeta(double rad,double mas,
  70.     double x, double vx, double y=0,double vy=0,double z=0,double vz=0)
  71.     :ObjetoCeleste(x,y,z,vx,vy,vz),Masa(mas),Radio(rad){}  
  72.   void SetColor(float r,float g,float b){Color[0]=r;Color[1]=g;Color[2]=b;}
  73.   void Pintar();
  74.   void Itera(ListaObjetos &lista);
  75. };
  76.  
  77.  

Como puedes ver existen 3 clases:

ListaObjetos: que es una clase que implementa un "cajon" de capacidad 100 donde ir guardando los objetos del planetario.

ObjetoCeleste:Que puede ser cualquier cosa que haya por el universo,un planeta,una estrella, un agujero negro etc.Por lo tanto esta seria la clase de la que heredarian todas las demas en el planetario.Como puedes ver tiene 2 atributos que pueden compartir todos los objetos del universo, la velocidad y la posicion.Y tiene 2 metodos virtuales (Aki esta el kit de la cuestion y que creo no te han comentado los compañeros) Un metodo virtual es un método de una clase base que puede ser redefinido en cada una de las clases derivadas de esta, y que una vez redefinido puede ser accedido por medio de un puntero o una referencia a la clase base, resolviéndose entonces la llamada en función del objeto referido en vez de en función de con qué se hace la referencia.
Que viene a significar que si en una clase base definimos un método como virtual, si
este método es superpuesto por una clase derivada, al invocarlo utilizando un puntero o una referencia de la clase base, se ejecutará el método de la clase derivada.

Por tanto en el ejemplo del planetario la clase derivada Planeta tiene otros 2 metodos itera y pintar de igual nombre que en la clase padre por ser polimorficos.
El metodo pintar esta redefinido en la clase planeta por que un planeta no se pinta igual que una estrella o que otro objeto celeste
El metodo itera no se redefine porque lo unico que hace es recalcular la posicion en base a la posicion anterior y la velocidad.Como velocidad y posicion son atributos identicos para todos los objetos del planetario, basta con que el metodo lo implemente la clase padre.

Entonces el asunto funcionaria asi:

Creo una lista de objetos ---> ListaObjetos milista;
Meto los objetos mediante el metodo AgregarObjeto (tambien se pueden meter una vez iniciado el bucle de accion)
Tendre un timer o un bucle infinito que en cada vuelta llame a las funciones:
milista.Itera();
milista.Pinta();
que se encargaran de llamar a los metodos itera y Pintar de cada objeto de la lista
Si milista tuviera por ejemplo el siguiente contenido {planeta,estrella,planeta,agujero}

cuando milista.Pinta que hace un bucle recorriendo toda la lista hiciera milista.lista[0]->Pintar(); llamaria al metodo de Pintar de la clase Planeta, o milista.lista[1]->Pintar(); llamaria al de estrella, asi para todos.Sin embargo la llamada a itera seria igual para todos, es decir seria el metodo de la clase ObjetoCeleste.

Respecto tu problema de crear una lista o mas, yo creo que en principio debieras meter en una lista todo lo que pudieras que tenga la suficiente relacion para heredarlo de una clase principal,ya que resulta bastante mas comodo recorrer una sola lista.Basicamente se podria heredar todo de una clase que tenga de atributo solo la posicion, a partir de ahi lo que se te ocurra, objetos estaticos o con movimiento, de aire, tierra,agua, etc etc

Ufff, espero no haberte liado mas.  :lol:

salu2   :hola:

Renatus

  • Miembro activo
  • **
  • Mensajes: 27
    • Ver Perfil
Re: Les Pido Ayuda
« Respuesta #7 en: Miércoles 14 de Septiembre de 2005, 16:42 »
0
Muchas Gracias Diodo  :lol: .
Lo que me has escrito ha sido de gran utilidad para mí.
Lejos de haberme liado, por el contrario me ha enseñado muchísimo  ;) .
Así que gracias de nuevo.

Y quiero decirles a Juank, Neko-sama, Diodo y todos en el foro que me pone muy contento el hecho de que no tengan problemas en compartir sus conocimientos
enseñando cosas cuando aparecen novatos como yo, deseosos de obtener respuestas.

Muchas gracias muchachos  ;)

Renatus
Es cosa mía o el modo 320x240x256 conserva todavía algo de magia?