domingo, 6 de septiembre de 2015

Crear juego RPG en C++ y Allegro 4 (6) - Scroll

Continuamos con el curso de crea tu juego RPG en C++ y Allegro. En esta entrega se hará que nuestro personaje pueda recorrer el extenso bosque, mediante la ayuda del scroll.



NOTA IMPORTANTE:
Para realizar este curso es necesario tener hecho los anteriores, ya que solo se hace referencia a cambios en el código.


Que es un scroll ?

Se denomina scroll, desplazamiento, al movimiento en 2D de los contenidos que conforman el escenario de un videojuego.

En el ejemplo anterior solo llegaba a mostrarse un trozo del mapa bosque, ya que la imagen es superior a la resolución utilizada en el programa ( 800x600 ). Por ello, se crea un scroll para que cuando el personaje se acerque a uno de los bordes de la pantalla, se desplace el escenario mostrando el resto del mapa.


 Programación

Dentro de mijuego.h se define una variable booleana para indicar si el mapa tiene o no desplazamiento, esta variable la llamamos desplaza, si es TRUE es que tiene desplazamiento.  También se definen las variables enteras desplazamiento_map_x y desplazamiento_map_y, estas variables contendrá el valor del desplazamiento del scroll segun su eje x, y. Estas variables se definen de forma global para que puedan ser utilizadas en todas las funciones.

En la funcion de carga_juego(), se inicializan las variables:

    desplazamiento_map_x=0;
    desplazamiento_map_y=0;     
    desplaza = false;

Se les da un valor de 0 y false, ya que inicialmente partimos de que el primer mapa no tendrá scroll.

En la función actualiza_juego(), se controla el desplazamiento del scroll mediante el siguiente codigo:

     if ( desplaza )
    {
         int d = desplazamiento / 2;
         // controla el desplazamiento del mapa si esta en los bordes
         if ( ax < 160 && desplazamiento_map_x > 0 )
         {                
              desplazamiento_map_x-=d;
              jugador.posiciona(ax+d,ay);
              ax = jugador.getx();
              ay = jugador.gety();              
              if ( ax < 60 && desplazamiento_map_x > 0  )
              {
                  desplazamiento_map_x-=d;
                  jugador.posiciona(ax+d,ay);                   
              }
         }
         if ( ay < 160 && desplazamiento_map_y > 0 )
         { 
              desplazamiento_map_y-=d;
              jugador.posiciona(ax,ay+d);
              ax = jugador.getx();
              ay = jugador.gety();                
              if ( ay < 60 && desplazamiento_map_y > 0 )
             { 
                  desplazamiento_map_y-=d;
                  jugador.posiciona(ax,ay+d);                  
             }
         }
         if ( ax > PANTALLA_ANCHO-160 && desplazamiento_map_x < fondo->w-PANTALLA_ANCHO )
         {
              desplazamiento_map_x+=d;
              jugador.posiciona(ax-d,ay);
              ax = jugador.getx();
              ay = jugador.gety();                
              if ( ax > PANTALLA_ANCHO-60 && desplazamiento_map_x < fondo->w-PANTALLA_ANCHO  )
              {
                  desplazamiento_map_x+=d;
                  jugador.posiciona(ax-d,ay);                   
              }              
         }          
         if ( ay > PANTALLA_ALTO-160 && desplazamiento_map_y < fondo->h-PANTALLA_ALTO )
         {
              desplazamiento_map_y+=d;
              jugador.posiciona(ax,ay-d);
              ax = jugador.getx();
              ay = jugador.gety();                
              if ( ay > PANTALLA_ALTO-60 && desplazamiento_map_y < fondo->h-PANTALLA_ALTO )
              {
                  desplazamiento_map_y+=d;
                  jugador.posiciona(ax,ay-d);
              }              
         }
         ax = jugador.getx();
         ay = jugador.gety();            
                 
    }

En lineas generales lo que hace el código es que cuando el jugador se acerca a uno de los bordes, ya sea por arriba, abajo, izquierda o derecha, cuando esta a menos de 160 pixel se realiza un pequeño desplazamiento del escenario, en el caso de que se siga acercando al borde y este de menos de 60 pixel, se realiza otro desplazamiento para evitar que el jugador quede fuera de pantalla. Este código debe de ir justo antes de la llamada del jugador.teclado().

Tambien se debe de cambiar la siguiente condición al completo.

    if (lugar == 2)
    {
         px = px + desplazamiento_map_x;     
         py = py + desplazamiento_map_y;     
    }

Para que actualice la posición del protagonista cuando haya un desplazamiento.

    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 ); 
              desplazamiento_map_x=0;
              desplazamiento_map_y=160; 
              desplaza=true;          
         }
         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 ); 
              desplazamiento_map_x=0;
              desplazamiento_map_y=0;  
              desplaza=false;         
         }
         break;  
    default:
         break;
    }         

Se añade en cada una de las fases el valor correspondiente, según tenga o no scroll el próximo mapa que va a cargar.

Y finalmente se añade el desplazamiento del scroll a la hora de pintar los escenarios en la función pinta_juego()

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 
             ax = desplazamiento_map_x; 
             ay = desplazamiento_map_y;
             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); 
}   

Y llegados a este punto ya se tendrá el escenario del juego con scroll.

Si quieres ver alguna de las anteriores entregas entra en el Contenido del Blog

Recuerda, si tienes algún problema con los ejemplos de la pagina, o alguna duda. Puedes plantear tu pregunta en el foro de programación:

9 comentarios:

  1. tengo un problema, tengo todo el codigo bien pero cuando voy a salir de la casa traspaso todo ademas no puedo pasar hasta el borde, y no puedo volver a entrara a la casa

    ResponderEliminar
    Respuestas
    1. Comprueba de que la imagen de choque tenga el color correcto, esto viene explicado en el tema anterior.

      Eliminar
    2. Como lo solucionaste Dark Mike ??
      Tengo el mismo problema que vos y el codigo está bien porque lo vengo copiando casi todo :/

      Eliminar
  2. Koday jejeje ya lo resolvi. pero, el unico problema que tengo ahora es que no me hace scroll

    ResponderEliminar
    Respuestas
    1. Mira la variable desplaza, tiene que tener el valor a TRUE, para indicar que el mapa actual tiene desplazamiento.

      Eliminar
  3. Tengo el mismo problema que el de arriba !!!
    */
    Cuando voy a salir de la casa traspaso todo ademas no puedo pasar hasta el borde, y no puedo volver a entrara a la casa
    /*

    Que hago ??
    Los colores están bien .... que hiciste vos Dark Mike para solucionarlo ??

    ResponderEliminar
    Respuestas
    1. Nacho, lo mas probable es que no hayas realizado el cambio que dicen en el tutorial, debes dirigirte al apartado donde evalua si el lugar en el que estas es el 2 y allí, debes agregar:
      if (lugar == 2){
      px = px + desplazamiento_map_x;
      py = py + desplazamiento_map_y;
      }

      al modificar esta instrucción, debería funcionar, por lo menos a mí me sucedía el mismo error y al hacer esto, se solucionó

      Eliminar
    2. Hola oye yo lo repare cambiandole el valor "rest" en mi ciclo while en el main.

      Eliminar
    3. yo lo he solucionado mirando el código de la sesión 10. estas cuatro líneas hacen la comprobación de los choques y deben ir al final de if(desplaza){.....} y justo antes del if(lugar ==1){....
      jugador.teclado();
      bool choca = false;
      int px = jugador.getx();
      int py = jugador.gety()+16;

      Eliminar