El trabajo propuesto

Cuando el usuario salga por un lado de la pantalla (en el que no haya pared), deberá aparecer en otra habitación contigua.

Forma de conseguirlo

Necesitamos varias pantallas, conectadas entre ellas. Hay varias formas de conseguirlo. Por ejemplo, imaginemos que nuestro mapa de juego tiene 3 pantallas de ancho y tres de alto:

Cuadricula Vacia

Podemos plantearlo como un array (de una dimensión) de habitaciones: numeramos las habitaciones de forma consecutiva, de la habitación 1 a la 9:

Cuadricula 1d

Esto tiene el inconveniente de que necesitaríamos información adicional para saber que la casilla que está por debajo de la 1 es la 4, o que la 7 no está a continuación de la 6, sino al principio de la siguiente fila. No es complicado, pero posiblemente sería más sencillo considerar la situación de las habitaciones como una matriz de dos dimensiones, al igual que hemos hecho con las casillas que componen cada habitación:

Cuadricula 2d

De este modo, tendríamos un array de 2 dimensiones para las habitaciones, y cada habitación a su vez contendría varias casillas que forman otro array de 2 dimensiones. El conjunto podría ser un enorme array de 4 dimensiones, como éste:

    static int[,,,] mapa = 
    {      // Comienzo del mapa de casillas
      {    // Primera fila de habitaciones
        {  // Habitacion (0,0)
          {1,2,1,1,1,2,1},
          {3,0,0,0,0,0,0},
          {3,4,3,4,3,1,1},
          {3,4,0,4,0,0,0},
          {3,4,3,4,3,4,3},
          {3,4,0,0,0,4,3},
          {3,1,1,4,1,4,3}
        },
        {  // Habitacion (0,1)
          {1,2,1,1,1,2,1},
          {0,0,0,0,0,0,3},
          {1,1,3,4,3,4,3},
          {0,0,3,4,3,4,3},
          {3,4,3,4,3,4,3},
          {3,4,3,4,3,4,3},
          {3,1,3,4,3,4,3}
        },
      },
      {    // Segunda fila de habitaciones
        {  // Habitacion (1,0)
          {3,2,1,4,1,4,1},
          {3,0,0,0,0,0,0},
          {3,1,1,4,3,1,1},
          {3,0,0,4,3,0,0},
          {3,4,3,4,3,4,3},
          {3,4,3,4,0,4,3},
          {1,1,1,1,1,1,3}
        },
        {  // Habitacion (1,1)
          {1,2,1,4,1,4,1},
          {0,0,0,0,0,0,3},
          {1,1,1,4,1,1,3},
          {0,0,0,4,0,0,3},
          {1,4,3,4,3,4,3},
          {3,4,3,4,0,4,3},
          {1,1,1,1,1,1,3}
        },
      },
    };

Para desplazarnos, bastará con que si estamos en la última columna y el usuario pulsa la tecla de movernos a la derecha, deberemos pasar a la primera columna de la pantalla que hay a su derecha (daremos por sentado que el mapa está bien diseñado y que no hay huecos de una pantalla que coincidan con paredes en la pantalla adyacente):

if (Hardware.TeclaPulsada(Hardware.TECLA_DER) )
    if (x == maxX)
    {
      x = 0;
      columnaHabitacion++;
    }
    else if (x < maxX)
      if ((mapa[filaHabitacion, columnaHabitacion, y,x+1] == 0)  // Espacio en blanco
        || (mapa[filaHabitacion, columnaHabitacion, y,x+1] == 4) )// Escalera
          x++;

(Habría que hacer el mismo cambio en las cuatro direcciones de movimiento)

La apariencia de estas cuatro pantallas conectadas sería ésta:

Apariencia de la version 0.10

Y el fuente completo podría ser así:

/** 
 *   Juego: Logica de juego
 *  
 *   @see Hardware
 *   @author 1-DAI IES San Vicente 2009/10
 */
 
/* --------------------------------------------------         
   Parte de Death Pit - Remake
   Versiones hasta la fecha:
 
   Num.   Fecha       Por / Cambios
   ---------------------------------------------------
   0.01  08-Sep-2009  Nacho Cabanes
                      Version inicial: muestra una imagen
   0.02  07-Oct-2009  Nacho Cabanes
                      Mueve el personaje hacia la derecha
                        hasta llegar al margen
   0.03  13-Oct-2009  Nacho Cabanes
                      El personaje se mueve con flechas
                      Un primer enemigo que se mueve a la vez
   0.04  16-Oct-2009  Nacho Cabanes
                      Primera pantalla de presentacion
                      El primer enemigo rebota en los lados
                      Un segundo enemigo nos persigue
   0.05  20-Oct-2009  Nacho Cabanes
                      Array de enemigos (murcielagos)
                       que rebotan en los lados
   0.06  28-Oct-2009  Nacho Cabanes
                      Array bidimensional para imagen de fondo
   0.07  04-Nov-2009  Nacho Cabanes
                      El personaje se mueve solo por los "huecos"
                      Eliminados los enemigos (por ahora)
                      Renombradas variables i,j a fila,colum
   0.08  10-Nov-2009  Nacho Cabanes
                      Varias funciones para que el fuente sea mas modular
   0.09  16-Nov-2009  Nacho Cabanes
                      Varias pantallas conectadas
 ---------------------------------------------------- */
 
 using System; // Para numeros aleatorios: System.Random
 
public class Juego
{
 
    // Variables que usaremos: una imagen y un tipo de letra
    static ElemGrafico imagenPersonaje,
      presentacion;
    static ElemGrafico imagenFondoHoriz,imagenFondoHorizAcido,
      imagenFondoVert, imagenEscalera;
    static Fuente fuente18;
    static int fila, colum;  // Para recorrer 
 
    static short x=1, y=1;
    static short minX = 0, maxX = 6,
      minY = 0, maxY = 6;
 
    static int filasPantalla = 7;    
    static int columnasPantalla = 7;
 
    static int filaHabitacion = 0;
    static int columnaHabitacion = 0;
 
    static int[,,,] mapa = 
    {      // Comienzo del mapa de casillas
      {    // Primera fila de habitaciones
        {  // Habitacion (0,0)
          {1,2,1,1,1,2,1},
          {3,0,0,0,0,0,0},
          {3,4,3,4,3,1,1},
          {3,4,0,4,0,0,0},
          {3,4,3,4,3,4,3},
          {3,4,0,0,0,4,3},
          {3,1,1,4,1,4,3}
        },
        {  // Habitacion (0,1)
          {1,2,1,1,1,2,1},
          {0,0,0,0,0,0,3},
          {1,1,3,4,3,4,3},
          {0,0,3,4,3,4,3},
          {3,4,3,4,3,4,3},
          {3,4,3,4,3,4,3},
          {3,1,3,4,3,4,3}
        },
      },
      {    // Segunda fila de habitaciones
        {  // Habitacion (1,0)
          {3,2,1,4,1,4,1},
          {3,0,0,0,0,0,0},
          {3,1,1,4,3,1,1},
          {3,0,0,4,3,0,0},
          {3,4,3,4,3,4,3},
          {3,4,3,4,0,4,3},
          {1,1,1,1,1,1,3}
        },
        {  // Habitacion (1,1)
          {1,2,1,4,1,4,1},
          {0,0,0,0,0,0,3},
          {1,1,1,4,1,1,3},
          {0,0,0,4,0,0,3},
          {1,4,3,4,3,4,3},
          {3,4,3,4,0,4,3},
          {1,1,1,1,1,1,3}
        },
      },
    };
 
    static bool partidaTerminada;
 
    static void inicializar()
    {
        // Inicializo modo grafico 800x600 puntos, 24 bits de color
        Hardware.Inicializar(800, 600, 24);
 
        // Cargo imagenes y tipos de letra
        imagenPersonaje = new ElemGrafico("imagenes/personaje.png");
 
        imagenFondoHoriz = new ElemGrafico("imagenes/fondo1.png");
        imagenFondoHorizAcido = new ElemGrafico("imagenes/fondo2.png");
        imagenFondoVert = new ElemGrafico("imagenes/fondo3.png");
        imagenEscalera = new ElemGrafico("imagenes/escalera.png");
 
        fuente18 = new Fuente("FreeSansBold.ttf", 18);
        presentacion = new ElemGrafico("imagenes/present.png");
    }
 
    static void mostrarPresentacion()
    {
        //dibujo la presentacion
        presentacion.DibujarOculta();
 
        // Finalmente, muestro en pantalla
        Hardware.VisualizarOculta();  
 
        //hasta que se pulse espacio
        do {
 
        } while (! Hardware.TeclaPulsada(Hardware.TECLA_ESP) );
 
        //borro la presentacion
        Hardware.BorrarPantallaOculta(0,0,0);    
    }
 
    static void comprobarTeclas()
    {
          // Y lo muevo si se pulsa alguna flecha del teclado
          if (Hardware.TeclaPulsada(Hardware.TECLA_DER) )
            if (x == maxX)
            {
              x = 0;
              columnaHabitacion++;
            }
            else if (x < maxX)
              if ((mapa[filaHabitacion, columnaHabitacion, y,x+1] == 0)  // Espacio en blanco
                || (mapa[filaHabitacion, columnaHabitacion, y,x+1] == 4) )// Escalera
                  x++;
 
          if(Hardware.TeclaPulsada(Hardware.TECLA_ARR) )
            if (y == 0)
            {
              y = maxY;
              filaHabitacion--;
            }
            else if ( y > 0)
              if ((mapa[filaHabitacion, columnaHabitacion, y-1,x] == 0)  // Espacio en blanco
                || (mapa[filaHabitacion, columnaHabitacion, y-1,x] == 4) )// Escalera
                  y--;
 
          if (Hardware.TeclaPulsada(Hardware.TECLA_IZQ) )
            if (x == 0)
            {
              x = maxX;
              columnaHabitacion--;
            }
            else if ( x > 0)            
              if ((mapa[filaHabitacion, columnaHabitacion, y,x-1] == 0)  // Espacio en blanco
                || (mapa[filaHabitacion, columnaHabitacion, y,x-1] == 4) )// Escalera
                  x--;
 
 
          if (Hardware.TeclaPulsada(Hardware.TECLA_ABA) )
            if (y == maxY)
            {
              y = 0;
              filaHabitacion++;
            }
            else 
            if (y < maxY)
              if ((mapa[filaHabitacion, columnaHabitacion, y+1,x] == 0)  // Espacio en blanco
                || (mapa[filaHabitacion, columnaHabitacion, y+1,x] == 4) )// Escalera
                  y++;   
 
          if (Hardware.TeclaPulsada(Hardware.TECLA_ESC))
              partidaTerminada = true;
    }
 
    static void moverElementos()
    {
        // Nada que mover en esta version
    }
 
    static void comprobarColisiones()
    {
        // Nada que comprobar en esta version
    }
 
    static void dibujarElementos()
    {
          Hardware.BorrarPantallaOculta(0,0,0);
 
          // Dibujo el fondo de la pantalla
          for (fila=0; fila<filasPantalla; fila++)
            for (colum=0; colum<columnasPantalla; colum++)
              switch (mapa[filaHabitacion, columnaHabitacion, fila,colum]) {
 
                case 0:  // Espacio en blanco, no dibujo nada
                    break;
 
                case 1:
                    imagenFondoHoriz.MoverA( (short) (colum*70) , (short) (fila*50));
                    imagenFondoHoriz.DibujarOculta();
                    break;
 
                case 2:
                    imagenFondoHorizAcido.MoverA( (short) (colum*70) , (short) (fila*50));
                    imagenFondoHorizAcido.DibujarOculta();
                    break;
 
                case 3:
                    imagenFondoVert.MoverA( (short) (colum*70) , (short) (fila*50));
                    imagenFondoVert.DibujarOculta();
                    break;
 
                case 4:
                    imagenEscalera.MoverA( (short) (colum*70) , (short) (fila*50));
                    imagenEscalera.DibujarOculta();
                    break;
 
              }
 
          // Dibujo el personaje, el enemigo y un texto en la pantalla oculta
          imagenPersonaje.MoverA( (short) (x*70) , (short) (y*50) );
          imagenPersonaje.DibujarOculta();
 
          Hardware.EscribirTextoOculta(
                "Pulsa ESC para salir",
                300, 500, 0xAA, 0xAA, 0xAA, fuente18);
 
          // Finalmente, muestro en pantalla
          Hardware.VisualizarOculta();        
 
    }
 
    static void pausaFotograma()
    {
        // Pausa para 25 fps
        Hardware.Pausa( 40 );
    }
 
 
    static void buclePrincipal() {
      partidaTerminada = false;
      do {
        comprobarTeclas();
        moverElementos();
        comprobarColisiones();
        dibujarElementos();
        pausaFotograma();
      } while (! partidaTerminada);
    }
 
    public static void Main() {
      inicializar();
      mostrarPresentacion();
      buclePrincipal();
    }
 
} /* fin de la clase Juego */
 

Siguiente entrega...