lunes, 30 de mayo de 2011

GameEngine: Capitulo 1. Core Manager

Hola a todos...

He aquí la primera entrega "Como crear tu propio motor de videojuegos y no morir en el intento".

Antes que nada hay que dejar un par de puntos muy claros:
  1. Para mi es un proyecto vital, es decir, me podré estar toda la vida haciendolo y esto es un hecho que asumo debido a que quiero aprender, no a acabar un producto en un tiempo determinado. Lo digo por que en muchas ocasiones existe el fenomeno "esto lo acabo en 1 semana" muy propio de los novatines, que acostumbra a acabar en tragedia y lloros (y como daño colateral, abandonar el proyecto)
  2. En la medida de lo posible no usaré librerias de terceros (aunque si API's y algún que otro código suelto). Esto es debido a que por un lado no aprenderiamos (que entiendo que es nuestro objetivo principal) y por otro lado siempre podemos tener sorpresas desagradables con las licencias. No obstante, que yo no use librerias no significa que vosotros no podais, la idea es que el diseño del motor sea lo suficientemente solido y modular como para aceptar cambios de bloques enteros sin modificar la funcionalidad total.

Una vez dicho esto, pongamonos a trabajar.

El motor lo implementaré en C++ y aquí si que hay poca discusión. Soy un enamorado rematado de C y de ASM, pero en cuanto a modularidad C++ no tiene comparación. Como siempre, sois libres de montarlo como querais. Con lo que yo muestre por aquí no deberia haber problema en implementar el motor en Java(por ejemplo)..... aunque, quien en su sano juicio querría hacer eso? :D

Mi entorno de desarrollo es Windows y utilizo VisualStudio. Nuevamente, hacedlo en el compilador que querais ( DevCpp, gcc sobre Linux,etc... ), yo lo mostraré en el que tengo. Si no teneis ninguno en especial creo recordar que existe una versión Express del Visual Studio de gratix...

Como crear el proyecto:
Ahora que está todo dicho, crearemos el proyecto:
  1. Abrís el Visual Studio y creais un nuevo proyecto.
  2. Win32 >> Aplicación de consola Win32
  3. Siguiente
  4. Marcad "Aplicación de consola" y "Proyecto vacío"
  1. Finalizar

Las primeras lineas de código:

Ahora tendremos un proyecto mondo y lirondo, absolutamente sin ningun archivo.

Como ya supondreis, lo primero que haremos será crear un archivo que llamaremos main.cpp y otros dos a los que llamaremos Core.h y Core.cpp.

Copiad el siguiente código en los siguiente archivos:

main.cpp
/**************************************************************************************************/
// Código creado por F.Bordas (LordPakus) como ejemplo de creación de un game engine
// para el blog LordPakus (http://lordpakus.blogspot.com/).
// Prohibida la distribución fuera de este blog sin el permiso expreso del autor
/**************************************************************************************************/

/**************************************************************************************************/
// main.cpp : Main de nuestro gameEngine
/**************************************************************************************************/

#include "Core.h"

int main (int argc, char* argv[])
{
//Inicializamos la clase Core con los argumentos del programa
Core::singleton().Init(&argc, argv);

//Empezamos el programa dandole el control al bucle principal de la clase core.
Core::singleton().Run();

//Desinicializamos la clase Core
Core::singleton().DeInit();
}


Core.h
/**************************************************************************************************/
// Código creado por F.Bordas (LordPakus) como ejemplo de creación de un game engine
// para el blog LordPakus (http://lordpakus.blogspot.com/).
// Prohibida la distribución fuera de este blog sin el permiso expreso del autor
/**************************************************************************************************/

/**************************************************************************************************/
// Core.h : Interface del core manager.
// Caracteristicas especiales: Esta clase implementa un singleton, es decir, solo podrá existir un objeto de esta clase en todo el proyecto
/**************************************************************************************************/

#ifndef __Core__
#define __Core__

class Core
{
private:
// Constructor y destructor de la clase
static Core instance;
Core();
~Core();

public:
static Core& singleton();

public:
//Funcion para inicializar el bucle principal
void Init(int* argc, char* argv[]);

//Funcion para ejecutar el bucle principal
void Run();
//Funcion para desinicializar el bucle principal
void DeInit();
private:
};

#endif


Core.cpp

/**************************************************************************************************/
// Código creado por F.Bordas (LordPakus) como ejemplo de creación de un game engine
// para el blog LordPakus (http://lordpakus.blogspot.com/).
// Prohibida la distribución fuera de este blog sin el permiso expreso del autor
/**************************************************************************************************/

/**************************************************************************************************/
// Core.cpp : Código del core manager.
/**************************************************************************************************/

#include "Core.h"

#include <iostream> //Usada para imprimir por consola

using namespace std;

//Instancia única del core manager
Core Core::instance;

//Constructor
Core::Core()
{
}

//Destructor
Core::~Core()
{
}

//Devolvemos el puntero al singleton
Core& Core::singleton()
{
return instance;
}

//Funcion para inicializar el bucle principal
void Core::Init(int* argc, char* argv[])
{
cout << "Inicializamos el Core Manager\n";
}

//Funcion para ejecutar el bucle principal
void Core::Run()
{
//Variable usada de iterador
int i = 0;
//Bucle fool para comprovar el funcionamiento de la clase core...
for( i = 0 ; i < 1000000; ++i)
{
if(!(i%10000))
cout << "Ejecutamos el paso de core numero: " << (i/10000) << "\n";
}

}

//Funcion para desinicializar el bucle principal
void Core::DeInit()
{
cout << "Desinicializamos el Core Manager\n";
}


Ahora compilad (no os deberia dar ningún error) Como los más avispados ya supondréis si ejecutáis el exe resultante en una ventana de cmd el resultado que debereis ver será:

Inicializamos el Core Manager
Ejecutamos el paso de core numero: 0
Ejecutamos el paso de core numero: 1
Ejecutamos el paso de core numero: 2
.
Ejecutamos el paso de core numero: 98
Ejecutamos el paso de core numero: 99
Desinicializamos el Core Manager

Y por hoy hasta aquí llegamos, tal vez os parezca poco, pero sin lo que se ha explicado no se podría desarrollar el resto del proyecto. Si habéis tenido problemas para entender el código, googlead, es imprescindible entender este código a la perfección debido a que es muy sencillo y la complejidad no va ha hacer más que incrementarse. Y bueno, dudas y sugerencias, para esto teneis el blog.

LordPakusBlog
Nos vemos, hasta el siguiente capítulo.

32 comentarios :

  1. Puede ser, hace ya mucho de este capitulo y tal vez me olvidara de algo... que error te da?

    ResponderEliminar
  2. Oh gracias por responder Pako, el post la verdad recontra interesante pero me da errores de definicion Mira lo compilo en Geany y tambien en Dev-Cpp pero da estos errores:

    Al compilar el main.cpp:

    undefined reference to `Core::singleton()

    y asi para todas "undefined reference, como 6"

    El Core.h, tengo entendido que los headers no se compilan asi que solo lo guarde.
    (Esto me funciona por lo general para cualquier aplicacion).


    El core.cpp me da error:
    (.text+0x104): undefined reference to `WinMain@16'


    La verdad trate muchas veces bro y no funca no se si sera algun error mio pero te pido favor corrijas en caso sea tuyo ya que el curso esta muy interesante y quisiera poder segirlo con regularidad =)

    ResponderEliminar
  3. A ver... yo lo he compilado con VisualStudio (hay la versión express que es gratuita) y me funciona... No será que en tu entorno de trabajo no tienes bien puestas las rutas de inclusión?

    Los .h podriamos decir que no se compilan como tal pero son extremadamente necesarios para que compilen los .cpp...

    Pasos que yo seguiria para resolver el problema:
    1.Yo probaria lo que te he dicho,revisar que las rutas de inclusión del proyecto las tienes bien

    2.Si no funciona, bajarte el Visual Studio y volverlo a probar.

    3.Si ni así funciona: Bajate el último capitulo del proyecto (capitulo 17 por ahora) de la zona de descargas. Copias el main.cpp y el core.cpp/ .h de este capitulo machacando lo que te has bajado. Si ni así te funciona mandame por mail capturas de pantalla del código y del error y seguiremos buscando.

    Suerte!!!!

    ResponderEliminar
  4. No hombre nada no funca, en los archivos que descargue no puedo compilar por que los includes estan en carpetas las cuales no estan definidas

    Y no yo no uso Visual Express uso Compiladores GNU pero no creo que deba darme problemas

    ResponderEliminar
  5. "en los archivos que descargue no puedo compilar por que los includes estan en carpetas las cuales no estan definidas " .Vale, es eso. Busca para tu compilador la manera de incluir un nueva carpeta de includes. En el DevCpp estaba en opciones de proyecto / rutas de inclusión o algo así.

    Lo de bajarte el ultimo proyecto es por que ya tiene las carpetas seteadas...

    A malas,si no te aclaras, agarra un ejemplo de cualquier otra cosa de por internet, que contenga un archivo main y otro archivo .cpp/.h y que puedas compilar, y substtuye esos archivos por lo que hay en este articulo...

    Recuerda de enviarme la captura de pantalla con toda la info que puedas...

    Nos vemos

    ResponderEliminar
  6. Funco al quitar el main.cpp y agregando lo de este en el Core.cpp ahi si corrio.

    ResponderEliminar
  7. Ah ya funco aunque no se me parece raro bueno regalo divino

    ResponderEliminar
  8. Hola Pako, yo como muchos otros agradecemos la fabulosa experiencia de compartir tus conocimientos y sobre todo a mostrarnos el corazon de un engine para video juegos (quien no a disfrutado un videojuego), en lo personal yo trato de aprender hacer mi propio juego con RealityFactory el cual es en 3D completisimo para hacer de la A a la Z un video juego. Pero yo siempre me pregunte como es que hacen estas aplicaciones y por fortuna encontre tu blog, ahora yo soy un novatisimo en programacion solo tengo un conocimiento minimo de C++ y con animo de aprender, el problema en que me encuentro es que no entiendo muchas cosas aun cuando las investigo.
    En fin te agradesco por tu gran aporte y hare el mayor esfuerzo para comprender el codigo y tu manera peculiar de programar.

    ResponderEliminar
  9. Te agradezco muchisimo tu apoyo y el de los otros que posteais vuestras opiniones e inquietudes...

    Date tiempo para aprender, nadie nace aprendiendo....

    Si te puedo ayudar en algo adicional, dimelo , que para eso estamos...

    Nos vemos..

    P.D: Que significa eso de "tu manera peculiar de programar"??? :D :D :D . tan malo soy? :D

    ResponderEliminar
  10. Hola Pako, muy bueno tu blog.
    Mi problema fundamental es que vengo del mundo java y en algunas cosas es muy distinto al c/c++ (sobre todo en lo relacionado a instrucciones de precompilador y namespace).
    Te quería preguntar para que sirve esto:

    #ifndef __Core__
    #define __Core__

    Entiendo que si no está definido "__Core__" lo define, pero para que??
    Gracias

    ResponderEliminar
  11. Esto del #ifndef loquesea #define loquesea sirve para que se cargue un archivo solo una vez (en c++ es más usual el #pragma once ). Es la forma más tipica de eliminar problemas de compilación por multiples inclusiones del mismo archivo.

    Cuando un archivo lo incluyes en diferentes lugares puede pasar que incluyas la definición de clases dos veces y el compilador se queja...

    En fin, haz el acto de fe de que hace falta :D

    Nos vemos

    ResponderEliminar
  12. Hola Pako, como agrego la carpeta scr en visual? agrego el include pero no encuantro como ligar scr. Y eso de tu manera peculiar no es un mal comentario al contrario, me refiero a que tu manera de programar es muy clara =)

    ResponderEliminar
  13. No hace falta ligar la carpeta scr, con que tengas los ficheros .cpp dentro del proyecto tienes suficiente...


    Respecto a lo de que mi manera de programar es muy clara, discrepo, pero bueno, a nadie le amarga un dulce, gracias por el apoyo....

    Nos vemos

    ResponderEliminar
  14. Hola Pako es que tengo una pregunta, que versión de visual studio utilizas vos, ya que la que yo utilizo es la versión 2005 pero al momento de depurar o darle click a debug me aparece que no se pudo crear la carpeta debug, y que no se encuentra el archivo .exe para ejecutar la shell del sistema o el mismo cmd, y por lo tanto no puedo logra que me cargue la pantalla negrita, otra pregunta la versión del visual que utilizas es gratis o es pagada, por que si es gratis podrías decirme o darme el link de donde descargarlo, ya que he estado bajando puros visual studios y ninguno me deja correr la shell, solo el 6.0 pero no reconoce muchos comandos. gracias de todas formas por tu tuto esta de maravilla.

    ResponderEliminar
  15. Buenas...
    En un ordenador tengo el 2010(de pago) y en el otro el 2008 Express. (gratuito) .

    Lo de que no te puede crear la carpeta de debug es muy raro.. no se que puede pasar... a alguien más le pasa lo mismo?? Intenta a instalarte una versión más actual, aunque me parece raro.

    Respecto el link, no me acuerdo, pero buscando en el sr. google : "Visual Studio Express Edition" seguro que lo encuentras rapido.

    Nos vemos

    ResponderEliminar
  16. uhy pako mil gracias pero si puedo te envió una imagen del error que me sale. ya que también me descargue el visual studio 2010 pero me sale el error del manifiest o algo así, y el visual 2008 express edition que tengo, voy a probarlo y si me arroja error te saco la foto del error y te lo envió; de resto uff te fajaste con este super tutorial ojala mas gente hiciera este tipo de tutos como el tuyo. de todas maneras gracias parce.

    ResponderEliminar
  17. Desdeluego,pasame las capturas que quieras y les echo un ojo....

    Me gustaria que los tutoriales fueran mejres, pero bueno, mi tiempo es reducido...

    Nos vemos y gracias por tu apoyo

    ResponderEliminar
  18. No, no solo es el apoyo sino también mi apreciación ya que vos eres un master en esto y pues en Internet no había conseguido una guía como esta, la que vos explicas aquí, y pues lo de cargar modelados ya que yo también le doy a lo de 3ds max 2011 y la posibilidad de cargar gráficos 2d y 3d emociona a cualquiera es por eso que sigo tu tutorial y ojala sigas así animo amigo mio. Si algún amigo me recomendara algún sitio para iniciarse en la programación y en videojuegos le diría que buscara por Lord Pakus que es el mejor bye. Ah y mira este es un link de donde me descargue el visual studio 2005 express edition pesa casi unas 3 gigas

    http://www.microsoft.com/downloads/es-es/details.aspx?FamilyID=94DE806B-E1A1-4282-ABC5-1F7347782553

    mi pregunta es este me servirá para desarrollar los ejercicios espero que si, pero gracias por todo amigo.

    ResponderEliminar
  19. Gracias de nuevo, vas a hacer que me sonroje :D

    La idea es esa, que el boca a boca vaya funcionando y que cada vez haya más gente que lea y colabore con el blog.

    Respecto al link que me has pasado, en principio es la versión que utilizo yo en el ordenador "malo" :D y me funciona a las mil maravillas

    Espero poder ayudarte

    Nos vemos

    ResponderEliminar
  20. Mira este es el error que me origino el programa visual studio 2008 después de colocar el código tal cual lo pusiste en este primer tutorial, podrías decirme que demonios pasa con el programa. Te lo agradecería.

    https://docs.google.com/leaf?id=0B6ePnMtlt0BeY2E3MTFiZDEtN2EwMS00N2E2LTk4MDktNGEwMmFmYjIzMGE2&hl=en_US

    ResponderEliminar
  21. Hola buenas,

    Parece que tienes un error de manifiesto...

    Es un tema de configuración del visual Studio...

    Si no voy equivocado: dentro del proyecto Prpoiedades > Configuracion Propiedades > Herramientas de Manifiesto > Entrada y Salida, y pon la opción Manifiesto Incrustado(o algo por el estilo, no me acuerdo bien ahora mismo) a "No".

    Con eso te deberia funcionar... ya me diras el q

    Nos vemos

    ResponderEliminar
  22. hola nuevamente amigo lorpakus y gracias por responderme, tengo una duda los service pack que vos utilizas en tu maquina son service pack 1, 2 o 3, por que me descargue un windows profesional xp service pack 3 y en ese no me deja crear el archivo .exe voy a adjuntarte un vídeo para que veas lo que me pasa bueno, de todas lord muchas gracias por compartir vuestros conocimientos.

    Otra cosa en el otro disco de mu pc tengo montado el windows 7 ultimate, y ahy tampoco me deja correr el archivo .exe es decir le digo generar solución, eliminando eso lo del manifiest y bien hasta ahy, pero cuando le doy click en debug para que me aparezca la ventanita del sistema, me dice que no se encontró el archivo misdocumentos/debug/xxxx.exe y no em lo deja crear y eso me pasa lo mismo con todas las versiones de los visual studios que me he descargado y la verdad estoy triste por que quiero seguir tu curso que re vacano, pero si tu conoces de otro programa similar a visual studio que soporte también las librerías házmelo saber para descargarlo y asi poder continuar con tu tuto que esta de maravilla.

    ResponderEliminar
  23. Ya cuando me pases el video te lo confirmo pero es posible que estés ejecutando con la flechita y no te esté pillando bien la ruta de los recursos... copia la carpeta Data(donde están los gráficos y sonidos) en la raiz donde se te genera el ejecutable... es posible que el problema te venga de ahí....

    De no ser así, podria ser alguna libreria mal linkada, en cuyo caso podrias mirarte este post http://lordpakus.blogspot.com/2011/09/game-engine-en-devcpp-inicio-del.html en que un compañero está haciendo el port del proyecto a DevCpp.

    Igualmente pasame el video que le pueda echar un ojo, que me hace curiosidad saber que es.

    ResponderEliminar
  24. HOLA LORDPAKUS MIRA ESTE ES EL VIDEO DEL QUE TE HABLABA MIRALO Y AYUDAME POR FAS QUE VEO MAS AMIGABLE LA INTERFAZ DEL VISUAL STUDIO QUE LA DEL DEV.CPP

    ESTE ES EL LINK DEL VIDEO.
    https://docs.google.com/leaf?id=0B6ePnMtlt0BeMjVjYTdjMjQtMGU1Mi00MGQ3LTkyYzEtY2IwMjFlOWNmMmMy&hl=en_US

    ResponderEliminar
  25. Me parece que ya se lo que te pasa... cuando incluyes archivos lo haces a través de archivo->nuevo.. pero si te fijas, en el proyecto no te aparece ningún archivo, es decir, los archivos que creas no están relacionados con el proyecto.

    Encima de la carpeta archivos de código fuente, botón derecho, agregar->Nuevo elemento->código (Archivo c++ o Archivo de encabezado, depende de lo que queramos). En la zona de abajo donde te pone Nombre, pones el nombre del archivo, y en la ubicación pon la del proyecto, si no, no te verá los archivos...

    Si no te funciona dimelo y lo seguiremos mirando, pero estoy convencido que el problema que tienes viene de ahi....

    Si te funciona y quieres rehacer el video te lo subo al youtube como material de apoyo al capítulo, que realmente te ha quedado muy chulo (si quieres claro...)

    Nos vemos

    ResponderEliminar
  26. Hola Pakus, hace unos días encontré tu blog y hoy voy a comenzar a programar un GameEngine siguiendo tu guía. :)
    Capitulo 1 salió perfecto sin problemas, usando VS2010.

    Saludos

    ResponderEliminar
  27. Hola, me llamo Carlos y estoy intentado hacer con DEV++ un programa para hacer una quiniela que me ha mandado el profesor para antes de hoy a las 11:30. No funciona y ya no se que hacer. Me puedes ayudar?
    #include /* srand y rand */
    #include /* time */
    #include
    #include
    #include
    int main()
    {

    int num_aleat,num,contador;
    char car;
    do {
    system ("cls");
    srand(time(NULL));
    num_aleat=rand()%2;
    printf("\nNumero aleatorio: %d",num_aleat);
    if(num==0)
    printf("\n1");for (contador=1;contador<=15;contador++)
    {
    num=rand();
    num=num%2;
    if (num=0)
    printf("\n1");
    if (num=1)
    printf("\nX");
    else
    printf("\n2");
    }
    printf("Desea visualizar otro numero aleatorio: (s/n)?: ");
    car=getche();
    }while (car=='s');
    return 0;
    }

    ResponderEliminar
  28. int main()
    {
    int num_aleat,contador;
    char car;
    do {
    system ("cls");
    srand(time(NULL));

    for (contador=0;contador<=15;contador++)
    {
    num=rand();
    num=num%3;
    switch(num)
    {
    case 0:
    printf("\n1");
    break;
    case 1:
    printf("\nX");
    break;
    default:
    printf("\n2");
    break;
    }
    }
    printf("Desea visualizar otro numero aleatorio: (s/n)?: ");
    car=getche();
    }while (car=='s');
    return 0;
    }

    No lo he compilado, pero creo que te irá mejor así... pruebalo y ya dirás algo.

    De todas maneras, tendrás que trabajar más en programación.. .has hecho fallos de no fijarte.

    Nos vemos

    Pako

    ResponderEliminar
  29. Habia tocado las opciones de proyecto y no me funcionaba nada. Muchas Gracias por tu ayuda, aunque mi programa y el tuyo no hacen mas que repetir 1x2 seguido sin hacer mas variaciones, el programa si que compila y me ha servido.

    ResponderEliminar
  30. (...En la medida de lo posible no usaré librerias de terceros (aunque si API's y algún que otro código suelto)....)

    La verdad es preferible que uses uan biblioteca multiplataforma y no la API Win32.

    ResponderEliminar
    Respuestas
    1. Totalmente de acuerdo. De hecho si sigues mirando los capitulos de este tutorial u otros que tengo colgados todos acaban en librerias multi y no usando la API. Es la diferencia entre el planteamiento teorico inicial y la práctica.
      Gracias por tu aportación!!

      Eliminar

Related Posts Plugin for WordPress, Blogger...