08 enero 2010

JR to the Rescue

Después de haber realizado el juego Pequepon Adventures, necesitaba pasar el motor a 1024x768 y a 60 fotogramas por segundo, pero no quería tirarme otros 8 meses realizando un juego nuevo. Así que me propuse hacer un videojuego muy pequeño a una sola pantalla y basado en las antiguos videojuegos electrónicos más conocidos como los Game & Watch de Nintendo, a modo de homenaje para recordar como comenzaron las primeras consolas portátiles de videojuegos electrónicos.

Me he basado en concreto en la máquina Donkey Kong JR:

El apartado gráfico lo hemos hecho para que el usuario pueda elegir en las opciones la versión moderna y la clásica:


Esta sería la pantalla de juego en la versión moderna:

Y este sería exactamente igual en modo clásico simulando las pantallas de cuarzo:

El objetivo del juego es guiar al pequeño mono a la parte superior de la pantalla y rescatar a su padre que está encerrado. Para ello hay que saltar (con la barra de ESPACIO o la tecla Z) y coger la llave que liberará un trozo de los 4 que hay en la jaula hasta rescatarlo del todo. Cuando estemos delante de la jaula debemos pulsar la tecla ARRIBA para introducir la llave en la misma. También funciona con el joystick.

EL DESARROLLO DEL JUEGO

No os vayáis a pensar que un juego de estos se hace en dos tardes (eso pensaba yo). He tardado unos tres meses programando a ratos. No os podéis imaginar los quebraderos de cabeza que puede dar intentar reproducir una maquinita de estás. Han salido un total de 4600 líneas de código incluyendo las 1700 del motor 2D con polígonos.

Los recursos utilizados son exactamente igual que para el videojuego anterior: Delphi 7, SDL y OpenGL. Este sería el núcleo del juego donde he cambiado la rutina de temporización para controlar los fotogramas por segundo:

var
iFPS: Integer; // frames por segundo
iTmpInicial: Cardinal; // Tiempo al inicio del bucle
iTmpPrevio, iTmpActual: Integer; // Tiempo previo y actual

{$R *.res}

begin
InicializarSDL('Junior to the Rescue');
CargarOpciones;
ModoVideo(1024, 768, 32, True);
Teclado := TTeclado.Create;
Temporizador := TTemporizador.Create;
Joystick := TJoystick.Create;
Raton := TRaton.Create;
ControlSonido := TControlSonido.Create;
FijarVolumen;
InicializarLogotipo;

iTmpInicial := SDL_GetTicks;
iTmpPrevio := SDL_GetTicks;
iFPS := 0;

while not bSalir do
begin
iTmpActual := SDL_GetTicks;

if iTmpActual - iTmpPrevio > 1000 div 60 then
begin
Teclado.Leer;
Joystick.Leer;
Raton.Leer;
ControlarEventos;
ComenzarRender;
DibujarSprites;
FinalizarRender;
Temporizador.Incrementar;
Inc(iFPS);
if SDL_GetTicks - iTmpInicial >= 1000 then
begin
//SDL_WM_SetCaption(PChar(IntToStr(iFPS)), nil);
iFPS := 0;
iTmpInicial := SDL_GetTicks;
end;

iTmpPrevio := iTmpActual;
end
else
SDL_Delay(1);
end;

DestruirSprites;
FinalizarJuego;
Raton.Free;
Joystick.Free;
ControlSonido.Free;
Temporizador.Free;
Teclado.Free;
FinalizarSDL;
end.

La función que he desactivado es la que me mostraba los fotogramas por segundo en la barra de título cuando jugamos en modo ventana:

SDL_WM_SetCaption(PChar(IntToStr(iFPS)), nil);

Así tengo un control de como funciona en distintos PC y sistemas operativos. Es esta línea la que realmente controla los 60 fotogramas:

if iTmpActual - iTmpPrevio > 1000 div 60 then

Después de procesar 60 los fotogramas por segundo le devuelvo el control a Windows con:

SDL_Delay(1);

De este modo no tenemos que consumir el 100% del procesador como hacen otros juegos casuales que no se complican la vida. Hay que pensar que un juego que consuma mucho procesador más otros programas ejecutándose a la vez como Emule y Bittorrent pueden fundir la batería de un portátil en muy poco tiempo y no hay necesidad de ello.

El motor 2D es exactamente el mismo que utilicé para Pequepon Adventures salvo en lo que respecta a la resolución, donde hay que hacer algunos cambios al inicializar el modo de vídeo:

ModoVideo(1024, 768, 32, True);

Y la función más importante es la que establece el punto de vista en OpenGL:

procedure InicializarOpenGL(iAncho, iAlto: Integer);
var
rRatio: Real;
begin
rRatio := CompToDouble(iAncho) / CompToDouble(iAlto);

// Suavizamos los márgenes de los polígonos
glShadeModel(GL_SMOOTH);

// Ocultamos las caras opuestas
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);

// Ponemos el negro como color de fondo
glClearColor(0, 0, 0, 0);

// Configuramos el zbuffer
glClearDepth(1);

// Establecemos la perspectiva de visión
gluPerspective(60, rRatio, 1.0, 1024.0);

// Habilitamos el mapeado de texturas
glEnable(GL_TEXTURE_2D);

// Activamos el z-buffer
glEnable(GL_DEPTH_TEST);
glDepthMask(TRUE);

// Sólo se dibujarán aquellas caras cuyos vértices se hallen en sentido
// de las agujas del reloj
glFrontFace(GL_CW);

glViewport(0, 0, iAncho, iAlto);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, iAncho, 0, iAlto, -100, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
iUltimaTextura := 0;

// Para el log
iNumTexCre := 0;
iNumTexDes := 0;
iMemoriaVideo := 0;
end;

El resto del motor es exactamente igual que utilicé en los artículos anteriores.

DESCARGA DEL JUEGO

Como es natural en un juego tan pequeño, lo he publicado con licencia Freeware y puede descargarse de estos servidores:

http://www.filefront.com/15309069/Install_JR.exe

http://hotfile.com/dl/23267794/e747a02/Install_JR.exe.html

http://www.mediafire.com/download.php?yzmwzrkzhyy

El más rápido para descargar es HotFile. Esta es la página web oficial:

http://www.divernovagames.com/jrtotherescue.html

CONCLUSIONES

Una cosa que he aprendido en esto de la programación de videojuegos es que hay que comenzar con pequeños proyectos y distintos, de modo que nuestra librería se vaya enriqueciendo poco a poco pero intentando separar el motor 2D puro y la dinámica del juego, para poder reaprovecharlo en futuros proyectos. Mi siguiente objetivo es hacer un juego arcade para poner el motor a tope para ver hasta donde llega.

Pruebas realizadas en Delphi 7.

8 comentarios:

MAXIUM dijo...

EXCELENTE!!!

No dejo de visitar tu página, siempre estas con novedades y tus artículos finales son sorprendentes ya que estas cosas no solo son aplicables a video juegos ;)

Gracias.

Edgar Iván dijo...

Muy buen trabajo, se ve que es bastante dificil hacer un trabajo de este tipo, felicidades, solo una pregunta, con que programa generas tus instaladores ?

Administrador dijo...

Para generar las instalaciones utilizo el programa Inno Setup (que por cierto también está hecho en Delphi):

http://www.jrsoftware.org/isinfo.php

Aunque las instalaciones se hacen mediante un archivo de texto, verás que son muy sencillas y su ayuda es excelente. Por cierto, algún día tengo que escribir un articulo sobre este programa.

Saludos.

Edgar Iván dijo...

Muchas gracias por el dato, debo decir que te debo mucho ya que gracias a la información de tu blog pude sacar adelante muchas partes de mi proyecto final en la universidad. Saludos y sigue así.

Mario M. dijo...

Hola!
Molan los juegos. A ver si algún día hago algo en openGl.
Un cosa, al ejecutarlo se ven dos rayas final horizontales (se divide el juego en 3 rectángulos de... 1024x200 y pico).

Lo tienes controlado?
Tb me pasaba con el otro juego.

Saludos y animo!

Administrador dijo...

Hola Mario,

¿Puedes mandarme a mi correo una captura de esas pantallas? Me gustaría solucionar el problema, a ver si es cosa de las tarjetas gráficas o de mi librería:

taxylon@gmail.com

Saludos.

Abismo Neo dijo...

oye bro, te queria preguntar, como podria hacer uno de "wrestling" o uno de "baseball" ? me podrias dar unas ideas para ver como empezar? se que estas ocupado pero cualquier cosa me vendria bien para empezar... y a ver cuando pones mas tutos como los que has estado haciendo de juegos. estan geniales.

Administrador dijo...

Si nunca has realizado ningún videojuego semiprofesional, o por lo menos si nunca has terminado uno (aunque sea un cutre ping pong) entonces ni se te ocurra hacer esos tipos de juego porque te va a pasar lo mismo que a mi: no los vas a terminar en la vida.

Te recomiendo empezar por algo muy sencillo, como un pequeño matamarcianos (tipo galaxian) o un juego de inteligencia moviendo piezas.

Debes abarcar desde la presentación hasta el game over, incluyendo opciones, sonido, etc. Un juego sencillo puede tardar en hacerse unos 3 meses.

Cuento tengas 3 o 4 juegos pequeños realizados entonces tendrás una buena biblioteca de código para empezar algo grande.

Saludos.

Publicidad