From the category archives:

C/C++

Otro juego de fútbol multiusuario en el cual colaboré con la programación del lado del servidor. Lo interesante que tuvo este proyecto es que había bots que jugaban junto con el jugador y en su contra utilizando agentes y máquinas de estado.


Juego contra la computadora
Juego contra la computadoraLobby del juegoProgramé en mi laptop, pero con monitor y teclado

Otra cosa que me gustó de este proyecto es que apliqué "nuevas técnicas" que me permitieron desarrollarlo en tiempo récord desde cero.

{ 3 comments }

El cubo volador

by Jorge Machin on July 14, 2010 · 3 comments

in 3D, Adobe Flash, C/C++, Personal, Portafolio, Proyectos, Unity, videos

Una pequeña prueba de concepto para agregar figuras 3D a videos para juegos y otras aplicaciones.

Por supuesto que el guión no esta basado en algo que me haya pasado :)

{ 3 comments }

Obtener dinámicamente el tipo de una clase en C++

by Jorge Machin on August 14, 2009 · 0 comments

in C/C++

Cuando manejamos herencia, a veces es necesario poder diferenciar entre varias clases heredadas. Una forma ordenada de hacerlo, es declarar una variable tipo que nos identifique con que clase estamos trabajando. Otra opción es realizando un casting dinámico para aprovechar las propiedades RTTI (Run-time type information) de los objetos de C++. Si el casting nos regresa NULL es que no es del tipo que nos interesa.

A continuación presento un ejemplo que ilustra esta técnica:

#include <iostream>

using namespace std;

class Figura {

   public:

     // Es importante que la clase base sea polimorfica agregándole al menos una función virtual:

     virtual ~Figura() { };

};

class Triangulo : public Figura {

};

class Cuadrado : public Figura {

};

main() {

   Figura *figura1 = new Cuadrado;
   Figura *figura2 = new Triangulo;

   if ( dynamic_cast<Cuadrado *>( figura1 ) )

      cout <<"La figura1 es un Cuadrado" <<endl;

   else if ( dynamic_cast<Triangulo *>( figura1 ) )

      cout <<"La figura1 es un Triangulo" <<endl;

   if ( dynamic_cast<Cuadrado *>( figura2 ) )

      cout <<"La figura2 es un Cuadrado" <<endl;

   else if ( dynamic_cast<Triangulo *>( figura2 ) )

      cout <<"La figura2 es un Triangulo" <<endl;

   return 0;

}

Aquí lo puedes ver en acción: http://www.ideone.com/xAmv72e5

{ 0 comments }

Supongamos que tenemos las siguientes clases:

#include <iostream>

#include <boost/shared_ptr.hpp>

using namespace std;

class Base {

  public:

    virtual void imprime() { cout <<"Función imprime de la Clase Base" <<endl; }

    virtual ~Base() { cout <<"Destructor de la Clase Base" <<endl; }

};

typedef boost::shared_ptr<Base> base_ptr;

class Derivada : public Base {

  public:

    virtual void imprime() { cout <<"Función imprime de la Clase Derivada" <<endl; }

    virtual ~Derivada() { cout <<"Destructor de la Clase Derivada" <<endl; }

};

typedef boost::shared_ptr<Derivada> derivada_ptr;

Y queremos hacer esto:

int main() {

  derivada_ptr derivada( new Derivada );

  base_ptr base( derivada );

  base->imprime();

  //  La siguiente línea no va a compilar:

  derivada_ptr regreso( base );

  return EXIT_SUCCESS;

}

En la tercera declaración, nos va a marcar este error al compilar:

/usr/include/boost/shared_ptr.hpp:194: error: conversión inválida de ‘Base* const’ a ‘Derivada*’

Obviamente, necesitamos un casting. La forma para hacerlo sería así:

int main() {

  derivada_ptr derivada( new Derivada );

  base_ptr base( derivada );

  base->imprime();

  //  Ahora si compila:

  derivada_ptr regreso(  boost::static_pointer_cast<Derivada>( base ) );

  return EXIT_SUCCESS;

}

Al ejecutar el programa, obtenemos esta salida:

Función imprime de la Clase Derivada
Destructor de la Clase Derivada
Destructor de la Clase Base

Como se ve, el smart pointer funcionó a la perfección a pesar de todas las transformaciones.

{ 0 comments }

Functores a la boost

by Jorge Machin on December 31, 2008 · 2 comments

in C/C++, Snapshots

Para mí, una de las razones para considerar seriamente a boost en cualquier proyecto en C++ es su implementación de functores. Realmente facilita mucho la creación de funciones "callback" y "delegates" sin causar mucha penalización en el rendimiento de un programa.

¿Porqué facilita el trabajo si los callbacks bien se pueden hacer con tan solo un apuntador a función? La respuesta es fácil si estas trabajando con un enfoque orientado a objetos. Para usar un apuntador a una función miembro, esta necesita ser estática o ser llamada con ayuda de su objeto. Las dos cosas bastante engorrosas.

Veamos como se sortea estos inconvenientes usando boost:

#include <iostream>

#include <boost/function.hpp>
#include <boost/bind.hpp>

using namespace std;

class Callback {

  public:

     void set_callback_function( boost::function<void()> function ) {

       this->callback_function = function;

     }

     void execute_callback_function() {

       if(  !callback_function.empty() )

          callback_function();

     }

  private:

     boost::function<void ()> callback_function;

};

class MiClase {

  public:

     void funcion() {

        cout <<"¡iujú! ¡Si se llamó!" <<endl;

     }

};

int main() {

  Callback callback;

  MiClase miclase;

  callback.set_callback_function( boost::bind( &MiClase::funcion, &miclase ) );

  callback.execute_callback_function();

  return EXIT_SUCCESS;

}

Probando el código en línea

En la siguiente URL, puedes probar este programa en línea: http://www.ideone.com/hbMXbtFR

{ 2 comments }