Programación Específica > Programación de Videojuegos

 Les Pido Ayuda

<< < (2/2)

Renatus:
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

Diodo:
Hola

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


--- Código: Text --- class ObjetoCeleste; //Clase contenedora de Objetos Celestes. Utiliza memoria estática//por lo que como máximo almacenará hasta 100class ListaObjetos{  ObjetoCeleste *lista[100];  int num;public:  ListaObjetos(){num=0;}  ObjetoCeleste * operator[](int i)    {    if((i&#60;num)&&(i&#62;-1))return lista[i];    else return NULL;    }  bool AgregarObjeto(ObjetoCeleste *obj)    {    if(num&#60;100){lista[num++]=obj;return true;}    else return false;    }  void Itera();  void Pinta();  int GetNum(){return num;} }; class ObjetoCeleste{protected:  double posicion[3];  double velocidad[3];  int tipo;public:   ObjetoCeleste(double x, double y, double z,double vx,double vy,double vz)    {    posicion[0]=x;posicion[1]=y;posicion[2]=z;    velocidad[0]=vx;velocidad[1]=vy;velocidad[2]=vz;    }  virtual void Pintar(){}  virtual void Itera(ListaObjetos &lista)    {    for(int i=0;i&#60;3;i++)posicion[i]+=velocidad[i];    }  double operator -(ObjetoCeleste &obj)    {    double dist=0;    for(int i=0;i&#60;3;i++)      dist+=((posicion[i]-obj.posicion[i])*(posicion[i]-obj.posicion[i]));    return sqrt(dist);    }  void PrePintado()    {    glPushMatrix();    glTranslated(posicion[0],posicion[1],posicion[2]);    }  void PostPintado(){glPopMatrix();}};  class Planeta:public ObjetoCeleste{protected:  double Masa;  double Radio;  float Color[3];public:  Planeta(double rad,double mas,     double x, double vx, double y=0,double vy=0,double z=0,double vz=0)    :ObjetoCeleste(x,y,z,vx,vy,vz),Masa(mas),Radio(rad){}    void SetColor(float r,float g,float b){Color[0]=r;Color[1]=g;Color[2]=b;}  void Pintar();  void Itera(ListaObjetos &lista);};  
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:
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

Navegación

[0] Índice de Mensajes

[*] Página Anterior

Ir a la versión completa