Continuamos con el curso de crea tu juego RPG en C++ y Allegro. En esta entrega se hará que nuestro personaje pueda salir de la casa al exterior, y recorrer el bosque.
Si quieres ver alguna de las anteriores entregas entra en el Contenido del Blog.
Uno con la imagen completa del nuevo escenario, una segunda imagen con las zonas de choque, y una tercera imagen con las cosas por las que el protagonista pasará por debajo, como son las copas de los arboles. Es importante que las tres imágenes tengan el mismo tamaño.
El mapa de choque se utilizará para indicar con el color rojo las zonas que no podemos pisar, y por tanto chocaremos, y también con otros colores indicaremos otras acciones. En el ejemplo se utilizará el color azul para detectar la puerta de la casa.
Programación
/* mijuego.h */ BITMAP *casa_a; BITMAP *casa_b; BITMAP *casa_c; BITMAP *bosq_a; BITMAP *bosq_b; BITMAP *bosq_c; BITMAP *fondo; BITMAP *choque; BITMAP *cielo; player jugador; // indicará en que lugar estamos // 1: casa // 2: bosque int lugar; // carga todo lo necesario antes de empezar el juego void carga_juego() { jugador.inicia(); casa_a = load_bmp("casa.bmp",NULL); casa_b = load_bmp("casa-sup.bmp",NULL); casa_c = load_bmp("casa-choque.bmp",NULL); bosq_a = load_bmp("bosque.bmp",NULL); bosq_b = load_bmp("bosque-sup.bmp",NULL); bosq_c = load_bmp("bosque-choque.bmp",NULL); // cargamos imagenes del primer escenario fondo = casa_a; choque = casa_c; cielo = casa_b; lugar = 1; } // actualiza el estado del juego void actualiza_juego() { int cambio = 0; int ax,ay; ax = jugador.getx(); ay = jugador.gety(); jugador.teclado(); // comprobar si colisiona con el mapa bool choca = false; int px = jugador.getx(); int py = jugador.gety()+16; if ( lugar == 1) { px = jugador.getx()-160; py = jugador.gety()-160+16; } if (lugar == 2) { py=py+160; } for ( int ci=2; ci < 30; ci++) { for (int cj=0; cj < 16; cj++) { // color rojo if ( getpixel( choque, px+ci, py+cj) == 0xff0000 ){ choca = true; } // color verde if ( getpixel( choque, px+ci, py+cj) == 0x00ff00 ) cambio = 1; // color azul if ( getpixel( choque, px+ci, py+cj) == 0x0000ff ) cambio = 2; // color amarillo if ( getpixel( choque, px+ci, py+cj) == 0xffff00 ) salir = true; } } if ( choca ){ // vuelve al estado anterior jugador.posiciona( ax,ay ); } switch ( lugar ) { case 1: // casa if ( cambio == 1 ) { // cambiamos a otro lugar lugar = 2; fondo = bosq_a; choque = bosq_c; cielo = bosq_b; jugador.posiciona( 410,370 ); } break; case 2: // bosque if ( cambio == 2 ) { // cambiamos a otro lugar lugar = 1; fondo = casa_a; choque = casa_c; cielo = casa_b; // situamos al prota dentro de la casa jugador.posiciona( 290,440 ); } break; default: break; } } // Se encarga de pintar todo sobre el buffer void pinta_juego() { int ancho, alto; int ax=0; int ay=0; int bx=0; int by=0; switch ( lugar ) { case 1: // casa bx=160; by=160; ancho = 480; alto = 325; break; case 2: // bosque ay=160; ancho = PANTALLA_ANCHO; alto = PANTALLA_ALTO; break; default: break; } blit( fondo, buffer, ax, ay, bx, by, ancho, alto); jugador.pinta(); masked_blit( cielo, buffer, ax, ay, bx, by, ancho, alto); }
Todas las modificaciones se han realizado solo en el archivo mijuego.h, por tanto todos los demás archivos se dejan tal cual, solo se debe de sustituir este nuevo código y añadir las nuevas imágenes.
Paso a Paso
Se han declarado nuevas variables del tipo BITMAP, que son las que contendrá las imagenes de los escenarios. Se crea el concepto de fases, controlado con la variable lugar, que contendrá en que fase o lugar esta:
- 1 En la casa
- 2 En el bosque
En la función carga_juego(), cargamos todas las imágenes que se utilizarán en el programa. Las variables fondo, choque, y cielo, serán variables generales que indicaran el lugar actual en el que estamos, por tanto, siempre que se cambie de lugar (fase) se debe de actualizar estas variables con las nuevas imágenes del lugar.
for ( int ci=2; ci < 30; ci++) { for (int cj=0; cj < 16; cj++) { // color rojo if ( getpixel( choque, px+ci, py+cj) == 0xff0000 ){ choca = true; } // color verde if ( getpixel( choque, px+ci, py+cj) == 0x00ff00 ) cambio = 1; // color azul if ( getpixel( choque, px+ci, py+cj) == 0x0000ff ) cambio = 2; // color amarillo if ( getpixel( choque, px+ci, py+cj) == 0xffff00 ) salir = true; } }
En la función de colisión se han añadido algunas condiciones, según colores utilizados. Para el ejemplo utilizamos el rojo (0xff0000) para bloquear el paso del personaje, el verde (0x00ff00) para salir de la casa, el azul (0x0000ff) para volver al interior de la casa. Se han cambiado los valores del primer bucle for, ahora empieza en el 2 para acabar en el 29. Esto se ha realizado para reducir el tamaño de bloqueo del personaje, por tanto ahora el tamaño de choque es de 28x16, tal y como se muestra en la siguiente imagen el recuadro pintado de verde es lo que realmente se esta comprobando si choca.
En la función pinta_juego() siempre se pinta el fondo y el cielo. Lo único que va variando son los parámetros de muestra, que cambian según el escenario o lugar, para ello se crean las variables ax,ay, bx,by, ancho y alto. Estos datos cambian según las propiedades de las imágenes utilizadas para los escenarios.
En la función pinta_juego() siempre se pinta el fondo y el cielo. Lo único que va variando son los parámetros de muestra, que cambian según el escenario o lugar, para ello se crean las variables ax,ay, bx,by, ancho y alto. Estos datos cambian según las propiedades de las imágenes utilizadas para los escenarios.
Aqui teneis las Imagenes bosque comprimida en RAR.
Y aqui tienen el archivo mijuego.h comprimido en RAR.
Y aqui tienen el archivo mijuego.h comprimido en RAR.
Tengo un problema con esta sesión. Al hacer todas las modificaciones, sigue cortando el juego al salir por la puerta de la casa... He probado a lanzar excepción de allegro en caso de que no cargue bien las imágenes, pero se ve que ese no es el problema... ¿Una ayuda? Gracias. Por cierto, excelente curso: muy divertido, sencillo y muy bien explicado. Estoy deseoso de continuar con el :D
ResponderEliminarEste comentario ha sido eliminado por el autor.
EliminarBuenos tutoriales amigo
ResponderEliminaruna pregunta, Como funciona lo de getPixel? estoy algo confundido con la orientación de los ejes, por ejemplo por que si lugar==1 restas 160 pero si lugar==2 los sumas, no entiendo por que el cambio de operación, se supone que las dos imágenes las imprimiste a 160 en el eje Y.
pdt: el programa funciona correctamente
El getpixel obtiene el color de la imagen choque, segun la posicion del personaje. Con respecto a lo de restar o sumar 160 se debe a que la imagen casa es inferior al tamaño de pantalla y por ello tengo que sumar 160,160, ya que la imagen empieza a mostrarse en esa posición. En cambio la imagen del bosque es mayor que la pantalla, y da la coincidencia que le doy a "ay"el valor de 160, para que la imagen bosque salga centrada en pantalla, ya que este valor indica desde donde empieza a mostrar la imagen, desde la posición (0,160) "esquina superior izquierda" hasta (800,760) "esquina inferior derecha".
EliminarGracias por los tutos bro, queria preguntar que programa usas para crear los escenarios?
ResponderEliminarLas imagenes son sacadas del RPG MAKER y montadas con el Adobe Photoshop.
EliminarHola man, hace tiempo estaba recién aprendiendo a programar cuando vi este tutorial. Y volví a el a releer un poco para retomar un poco la programación en C++. Solo quería decirte que muchísimas gracias por tu aporte y el tutorial realmente me sirvió mucho.
ResponderEliminar