jueves, 7 de julio de 2011

C++:Uso de metodos virtuales en herencias

Hola, he tenido una semana algo atareada por otro proyecto que es mas importante en este momento para mi, así que tendré paciencia en seguir trabajando con OpenFrameworks y me aguantaré un poco las ganas de aprender al máximo esta herramienta.

Trabajando un poco con clases heredadas en c++, me encontré con un concepto que utilizo mucho en c# como las clases base con métodos virtuales y métodos que se sobre-escriben en las clases hijas, concepto importante para poder manipular diferentes comportamientos pero que por parentesco se relacionan en algún punto de la aplicación.

En el primer proyecto que tengo tengo otras definiciones y otras clases, pero explicaré con otro tipo de contexto mas entendible como para que no se olvide.

Antes de iniciar la explicación de las experiencias, debemos tener en cuenta el contexto: hay una clase base llamada "Humano" y otra clase llamada "Carlos".

Experiencia 1: (Como se haría en C#, de hecho es algo parecido a C++)

//Clase Humano
abstract class Humano
{
public virtual void comer()
{
//el ser humano come de una manera común (todo entra por la boca, no se puede discutir esto... jejeje XD)
}
}

//Clase Carlos
public class Carlos: Humano
{
public overwrite void comer()
{
//carlos tiene un estilo diferente de comer(es decir, carlos puede coger el tenedor o los cubiertos con un estilo propio a carlos)
}
}

Mi primera experiencia con C++ fue:

//Clase Humano
class Humano
{
public:
virtual void comer();
}

//Clase Carlos
class Carlos: Humano
{
public:
void Humano::comer(){} <---------- ERROR: forma erronea de escribir el metodo sobre-escrito
}

La segunda experiencia fue: (referenciada del libro "Pensar en C++, tomo 1" en el capitulo "Polimorfismo y funciones virtuales")


//Clase Humano
class Humano
{
public:
virtual void comer();
}

//Clase Carlos
class Carlos: Humano
{
public:
void comer(){} <---------- casi obvio, pero tuve que consultar en el libro para saberlo
}

pero hay un detallito importante, si la funcion o el metodo no se sobre-escribe dentro del archivo Carlos.h si no que se va a sobre-escribir en el archivo Carlos.cpp, el metodo no debe ir en el archivo Carlos.h. Este detalle fue el que me dio dificultad tener en cuenta.

jueves, 30 de junio de 2011

C++: Uso del string

Hola, recientemente que estuve trabajando en un proyecto con cadenas de texto me encontré con ciertos detalles que se deben tener en cuenta:

1. Para trabajar con "strings" se puede utilizar la cabecera string, es decir, #include < string >
Cabe aclarar que no es lo mismo que ya que este ultimo no posee la declaración "string".
2. Usar "using namespace std" o utilizar "std::string"

Si se utiliza el archivo de cabecera iostream no es necesario incluir el archivo string

el código quedaría así:

#include <string>

using namespace std;
...
...

string [[nombre del objeto]];

Hasta pronto.

martes, 28 de junio de 2011

Dibujar círculos con OpenFrameworks

Volviendo del fin de semana y casi que continuando la practica del sonido, vuelvo a coger OpenFrameworks para dibujar figuras en pantalla y esta ves le toco al circulo.

Voy a montar una clase que hice para esta practica (si a alguien le interesa complementarlo, bienvenido sea, pero espero que se vuelva a montar lo que se complementó para que sea como un repositorio, la idea es aprender).

La clase se puede descargar desde esta url: https://sites.google.com/site/notasof/circulos-of

para iniciar la clase hay que escribir en la clase "testApp.cpp"...

En el metodo setup:

vector2D* center_pos = new vector2D(ofGetWidth()/2, ofGetHeight()/2);
Circle* aux_circle = new Circle(5, *center_pos, [[radio maximo permitido para los circulos como parametro]]);
circle = *aux_circle;
circle.setup();

En el metodo update:

circle.update([[incremento del radio de los circulos como parametro]]);

En el metodo draw:

circle.draw();

La clase esta debidamente comentada por si cualquier duda.
Gracias.

jueves, 23 de junio de 2011

Depurar accediendo a los archivos de la carpeta data

Esto es algo importante y que no había tenido en cuenta (ni si quiera sabia como solucionarlo) para poder reproducir un sonido desde el mismo debug de la aplicación en el IDE... y el problema era que no me estaba cargando un archivo .mp3 que estaba en la carpeta "bin/data/sounds" y cuando ejecutaba la aplicación directamente fuera del IDE efectivamente estaba cargando el recurso.
Pues la solución es la siguiente:

1. Abrir la ventana de propiedades del proyecto
2. Click en Depuración
3. Escribir en la casilla de "Directorio de trabajo" lo siguiente: "$(ProjectDir)/bin" (sin comillas)
4. Aplicar y Aceptar

Ya con esta configuración el Debug de la aplicación en el mismo IDE cargará el recurso que se desea cargar.

Configurar las directivas de salida en VS2010

1. Click derecho en el proyecto principal de la solución del panel "Explorador de soluciones"
2. Click en propiedades
Muestra la ventana de propiedades del proyecto
3. Click en General > Directorio de salida
copiar "bin\" (sin comillas)
4. Click en General > Directorios intermedios
copiar "obj\$(Configuration)\" (sin comillas)
5. Click en General > Nombre de destino
copiar "$(ProjectName)_debug"
6. Click en Aplicar y Aceptar

ya esta...

Proyecto 1 - Aprendiendo con sonidos

Antes de iniciar a trabajar con un nuevo proyecto, seguir este enlace:

Programando main.cpp:

#include
#include
#include"testApp.h"

int main()
{
ofAppGlutWindow window; //define un objeto ofAppGlutWindow
ofSetupOpenGL(&window, 800, 600, OF_WINDOW); //establece el modo de visualización
ofRunApp(new testApp());//arranca la aplicación
}

OF_WINDOW = es una constante entera que le indica a OpenGL arrancar la aplicación en modo ventana.
OF_FULLSCREEN = es una constante entera que le indica a OpenGL arrancar la aplicación en modo pantalla completa.

Programación de testApp.h y testApp.cpp:

primero hay que agregar una nueva clase, al realizar esta acción configuramos el nombre de la clase con el wizard que nos facilita el IDE y automáticamente nos crea los archivos de cabecera y de código, en este caso como se la clase se llama "testApp" entonces crea los archivos "testApp.h" y "testApp.cpp", teniendo la siguiente estructura:
archivo testApp.h:

#pragma once
class testApp
{
public:
testApp(void);
~testApp(void);
};

lo primero que se debe hacer es codificar la siguiente condición:
#idndef _TEST_APP
#define _TEST_APP
...
#endif

quedaría de la siguiente manera:
#idndef _TEST_APP
#define _TEST_APP

#include

#pragma once
class testApp
{
public:
testApp(void);
~testApp(void);
};
#endif

Notar que se hizo una inclusión del archivo de cabecera "ofMain.h" para poder utilizar el framework

Adicionalmente a esto, esta clase debe ir heredada de la clase interna del framework "ofBaseApp"

quedaría de la siguiente manera:
#idndef _TEST_APP
#define _TEST_APP

#include

#pragma once
class testApp: public ofBaseApp
{
public:
testApp(void);
~testApp(void);
};
#endif

Para poder iniciar a programar OpenFrameworks como tal hay que tener en cuenta estos métodos:
Setup: Método para establecer los valores y las condiciones iniciales de la aplicación.
Update: Método para actualizar constantemente la aplicación durante su ejecución.
Draw: Método para "dibujar" los elementos gráficos que hay en el escenario de la aplicación.

Quedaría de la siguiente manera con la definición de los métodos anteriores:
#idndef _TEST_APP
#define _TEST_APP

#include

#pragma once
class testApp: public ofBaseApp
{
public:
testApp(void);
~testApp(void);
void setup(void);
void update(void);
void draw(void);
};
#endif

Programación testApp.cpp:

Cuando el IDE crea el archivo muestra la siguiente estructura inicial:
#include "testApp.h"

testApp::testApp(void){}
testApp::~testApp(void){}

aquí se programan todos los método que tenga la clase (coloco esto por si alguien es newbie en c++ con poo).
Escribimos lo siguiente:
#include "testApp.h"

testApp::testApp(void){}
testApp::~testApp(void){}
void testApp::setup(void){}
void testApp::update(void){}
void testApp::draw(void){}

definir el siguiente objeto en el archivo testApp.h con cualquier tipo de encapsulamiento, en este caso se colocara como privado:

private:
ofSoundPlayer test_sound;

En testApp.cpp programar lo siguiente:

void testApp::setup(void)
{
test_sound.loadSound([direccion o ruta donde este el sonido]);
test_sound.play();
}
void testApp::update(void)
{
ofSoundUpdate();//Actualiza todos los sonidos
}

compilar y ejecutar...

NOTA:
tener en cuenta configurar las directivas de salida
tener en cuenta configurar el debug para poder acceder a archivos de la carpeta data

Este proyecto se quedará aquí por el momento.
Espero que sea de su agrado y cualquier problema lo discutiremos en este mismo post

Andrés Camilo
24 de Junio de 2011