/ SDL

Crear un juego – Parte IV (Anatomía y código)

En la parte II de esta serie de tutoriales les hable de lo que sería la anatomía de un videojuego, hoy vamos a ver esto, pero en la práctica y con SDL.

Como les comenté yo uso un IDE llamado Clion que este a su vez usa Cmake para los proyectos, así que hay que configurarlo, así que vamos por pasos, pero antes de empezar con los pasos quería comentar que también trabajaremos con la librería SDL_image.

Debido a que SDL por si solo trabaja con BMP, pero como sabemos este formato de imagen no cuenta con canales Alpha, haciendo que no tengan transparencias, así que para que una imagen BMP tenga su transparencia hay que especificar un color que omitirá al momento de hacer una rasterización y en caso de SDL seria al momento de hacer Blit o Flip.

Para que quede más claro nuestra imagen es la siguiente.

Como pueden ver hay un color que envuelve a nuestro personaje, si abrimos el Photoshop u otro programa para saber cuál es el color RGB de ese color que envuelve al Hero, seria R: 255 G: 0 B: 255.

Ahora le especificamos a SDL que la superficie que tiene la imagen (Sprite) uno de sus colores será omitido y esto se hace con:

// SDL_SetColorKey(sprite, SDL_SRCCOLORKEY,SDL_MapRGB(sprite->format, r, g, b)); //

Pueden ver que SDL_SetColorKey tiene 3 parámetros, el primero es la superficie que contiene el Sprite, el segundo es una constante para indicar que se activa y el tercero es un valor Color de SDL que se puede obtener con SDL_MapRGB, pasando también el formato del Sprite, más el color en RGB.

Y con esto ya tenemos un BMP transparente, pero si te quieres quitar la molestia de buscar el color, decirle a SDL que color debe omitir sería mejor cargar un PNG que soporta el canal Alpha mas aparte pesa menos que el BMP, para esto está la librería SDL_image, que su única función es cargar otros formatos.

Ahora si pasemos a los pasos a configurar nuestro entorno.

Lo primero es bajar la librería SDL y SDL_image, pero no solo el binario si no también el paquete de desarrollo (no el código fuente). Una cosa que se me olvido comentarles, ahorita hay 2 versiones de SDL, la 1.2 que ya tiene algunos años y que es laborioso en programarlo y la 2.0 la cual me baso, así que cuando bajemos una librería SDL como (SDL_NET o SDL_mixer) siempre fijos que es para la versión 2.0

Después de descargar las librerías, las descomprimiremos en una ubicación, así que traten que este cerca de la raíz de un Disco Duro, para que al momento de ponerle el Path en la configuración del IDE sea corta. Una vez descargada y puestas las dos librerías, tendrá 2 versiones, es decir, para 32Bits (i686-w64-mingw32) y 64Bits (x86_64-w64-mingw32) según para que sistema queremos configurarlo, pero ahorita solo nos centraremos en la de 32Bits.

Entonces tendremos esta estructura.

Lo segundo es abrir nuestro IDE y crear un proyecto con C++ 11 y esto nos generara un archivo CMakeLists.txt donde configuraremos el SDL y SDL_image para el Cmake, aunque hay Cmakes estandarizados para el SDL y lo pueden ver aquí, me gusta el mío por lo sencillo y también por nos sirve para el propósito de estudio, el cual ahorita se los mostrare.

Cuando abrimos nuestro archivo de configuración del Cmake, veremos que solamente tendremos estas líneas nada más.

cmake_minimum_required(VERSION 3.8) project(Anatomia) set(CMAKE_CXX_STANDARD 11) set(SOURCE_FILES main.cpp) add_executable(Anatomia ${SOURCE_FILES})

Ahora lo que haremos es agregar la configuración estándar del SDL, de hecho, lo pueden usar para futuras proyectos, solo deben especificar la ruta en donde está el SDL y para una muestra aquí está la configuración que yo uso.

cmake_minimum_required(VERSION 3.8) project(Anatomia) # PATH y FLAGS set(SDL2_Flags "-lmingw32") set(SDL2_ROOT "D:/DeveloperGames/SDL2/i686-w64-mingw32") set(SDL2_Includes "${SDL2_ROOT}/include") set(SDL2_LibDir "${SDL2_ROOT}/lib") set(SDL2_LibDll "${SDL2_ROOT}/bin") add_library(SDL2 STATIC IMPORTED) add_library(SDL2main STATIC IMPORTED) add_library(SDL2_image STATIC IMPORTED) set_property(TARGET SDL2 PROPERTY IMPORTED_LOCATION "${SDL2_LibDir}/libSDL2.a") set_property(TARGET SDL2main PROPERTY IMPORTED_LOCATION "${SDL2_LibDir}/libSDL2main.a") set_property(TARGET SDL2_image PROPERTY IMPORTED_LOCATION "${SDL2_LibDir}/libSDL2_image.a") set(SDL2_Libs mingw32 SDL2 SDL2main SDL2_image m dinput8 dxguid dxerr8 user32 gdi32 winmm imm32 ole32 oleaut32 shell32 version uuid) # FIN PATH y FLAGS set(CMAKE_CXX_STANDARD 11) set(SOURCE_FILES main.cpp) add_executable(Anatomia ${SOURCE_FILES}) #ADD SDL target_include_directories(Anatomia SYSTEM PRIVATE ${SDL2_Includes}) target_link_libraries(Anatomia ${SDL2_Libs}) # FIN ADD SDL

En la línea 6 es donde especifico la ruta al SDL y eso es todo lo que hay que cambiar, pero también quiero que recuerden que las líneas 28 y 29 debe ir el nombre del proyecto en este caso Anatomía.

En el siguiente paso (tercero) es copiar las DLL dependientes, aquí lo podemos hacer en la carpeta System32 o en la carpeta del ejecutable del juego, pero como a mí no me gusta contaminar mi System32 manualmente, lo que hago es copiar las DLL a la carpeta del proyecto del ejecutable.

Estos archivos se encuentran en donde pusimos el SDL (ver arriba la estructura de los archivos), más específicamente en la carpeta BIN y los archivos que deben copiar son:

  • libjpeg-9.dll
  • libpng16-16.dll
  • libwebp-4.dll
  • libtiff-5.dll
  • SDL2.dll
  • SDL2_image.dll
  • zlib1.dll

Cuando vayamos a la carpeta de nuestro proyecto veremos que hay una carpeta llamada cmake-build-debug, ahí es donde copiaremos estas librerías. Y con esto queda listo para empezar a programar en SDL.

Ahora pondré un código base que nos ayudará entender la anatomía de un videojuego y a su vez será nuestra base para ir implementando en los demás cursos.

include <SDL2/SDL.h> #include <SDL2/SDL_image.h> int main(int argc, char *argv[]){ bool quit = false; SDL_SetHint(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1"); if(SDL_Init(SDL_INIT_EVERYTHING) != 0){ SDL_Log("SDL_Init: %s", SDL_GetError()); return 1; } int flags = IMG_INIT_JPG | IMG_INIT_PNG; int initted = IMG_Init(flags); if((initted & flags) != flags){ SDL_Log("IMG_Init: %s", SDL_GetError()); return 1; } SDL_Window *_window; SDL_Renderer *_render; SDL_Event event = SDL_Event(); SDL_CreateWindowAndRenderer(480, 360, 0, &_window, &_render); SDL_SetWindowTitle(_window, "SDL Test - Curso"); while(!quit){ /Captura/ if(SDL_PollEvent(&event) != 0){ if(event.type == SDL_KEYDOWN){ if(event.key.repeat == 0){ } }else if(event.type == SDL_KEYUP){ }else if(event.type == SDL_QUIT){ quit = true; } } // /Procesar/ // /Actualizar/ // /Salida/ SDL_RenderClear(_render); SDL_RenderPresent(_render); // } SDL_DestroyRenderer(_render); SDL_DestroyWindow(_window); IMG_Quit(); SDL_Quit(); return 0; }

Como verán es algo básico pero lo suficiente para entender la anatomía de un videojuego y más para mostrar una ventana si lo ejecutamos y si recuerdan la anatomía de un videojuego, recordaran lo siguiente:

  • Iniciación
  • GameLoop - Entrada
  • Procesamiento
  • Salida
  • Finalización.

Entonces de acuerdo al código anterior, de la línea 5 al 26 correspondería a Iniciación, el GameLoop seria 28 al 56 y la finalización correspondería a 58 al 61. Ahora dentro del GameLoop la entrada seria entre las líneas 30 al 40, el procesamiento seria del 43 al 49 y la salida seria 52 al 54

Y para finalizar, esto es lo que me muestra al momento de compilarlo.

ilich

Programador Mexicano con 14 años de experiencia, ha incursionado en diferentes áreas ampliando su experiencia. Aprendí programación por que quería hacer mi propio video juego aun que he toca

Read More