Ver Mensaje Individual
  #5 (permalink)  
Antiguo 04/09/2015, 01:12
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Menu de Opciones en c++

Cita:
Iniciado por ALVIA2010 Ver Mensaje
bueno lo que me tratas de decir esque despues del main() cloque algo mas o menos asi
Int main(){

do{

cargar_laberinto();

}
while(????????))maki que coloco no entenderte muy bien..

y laparte de solo cargar la posision nueva.. lo intente pero tampoco ... pude.. me salta errores fatales
más bien me refería a algo así:

Código C++:
Ver original
  1. char seguir;
  2.   do
  3.   {
  4.     cargar_laberinto();
  5.    
  6.     gotoxy(52,7);cout<<"FELICIDADES...!!";
  7.     gotoxy(48,9);cout<<"1.-Recargar El juego..??"<<endl;
  8.     cin >> seguir;
  9.   } while( seguir == '1' );

En cuanto a lo de la posición se puede conseguir de muchas maneras. Si tuviese que hacerlo yo empezaría creando un struct para almacenar las coordenadas:

Código C++:
Ver original
  1. struct Coordenadas
  2. {
  3.   int x;
  4.   int y;
  5.  
  6.   Coordenadas( )
  7.   { x = -1; y = -1; }
  8. };

Al usar una estructura queda claro qué parámetro es la coordenada x y cual la coordenada y... con un arreglo tienes que saber la relación (en tu caso 0 -> y y 1 -> x pero podría ser tambíen al revés).

El constructor por defecto lo he implementado así para que, por defecto, las coordenadas no sean válidas... esto tiene su utilidad más adelante.

Luego, como necesitas almacenar dos posiciones (la antigua y la nueva), podemos crearnos otra estructura al uso:

Código C++:
Ver original
  1. struct PosicionJugador
  2. {
  3.   Coordenadas actual;
  4.   Coordenadas antigua;
  5. };

Con esto ya podríamos hacer la función que pinta el monigote:

Código C++:
Ver original
  1. void PintarPosicion( PosicionJugador& posicion)
  2. {
  3.   if( posicion.antigua.x >= 0 )
  4.   {
  5.     gotoxy( posicion.antigua.x, juego.antigua.y );
  6.     putchar( 0 );
  7.   }
  8.  
  9.   gotoxy( posicion.actual.x, posicion.actual.y );
  10.   putchar( 1 );
  11.  
  12.   posicion.antigua = posicion.actual;
  13. }

Y como ya tenemos un mecanismo para pintar el monigote podemos eliminar código de la función que pinta el laberinto:

Código C++:
Ver original
  1. void DibujarLaberinto(int matriz[][44]){
  2.  
  3.   for(int i=0; i<24; i++){
  4.     for(int j=0; j<44; j++){
  5.       if(matriz[i][j] == 1) cout <<(char)176;
  6.       else if(matriz[i][j] == 2) cout <<(char)176;
  7.       else if(matriz[i][j] == 3) cout <<(char)187;
  8.       else if(matriz[i][j] == 4 ) cout <<(char)188;
  9.       else if(matriz[i][j] == 0) cout<<" ";
  10.     }
  11.     cout << endl;
  12.   }
  13. }

Aunque claro, esta función como que tiene demasiadas cosas para lo que hace... no hace falta tener dos bucles para recorrer toda la matriz... con uno sobra. Además el switch se puede eliminar fácilmente si mapeamos los posibles tiles:

Código C++:
Ver original
  1. void DibujarLaberinto(int* matriz)
  2. {
  3.   char tiles[] = { ' ', (char)176, (char)176, (char)187, (char)188 };
  4.  
  5.   for(int i=0; i < FILAS * COLUMNAS; i++, matriz++)
  6.   {
  7.     cout << tiles[ *matriz ];
  8.     if( (i+1) % COLUMNAS == 0 ) cout << endl;
  9.   }
  10. }

Mas bonito, ¿no? primero mapeamos los tiles del laberinto, después recorremos la totalidad del laberinto y pintamos en cada posición el tile que le corresponde.

Claro que, para evitar warnings innecesarios podemos retocar un poco la variable que almacena el laberinto:

Código C++:
Ver original
  1. int matriz[FILAS*COLUMNAS] ={...

Vale, antes de alejarnos más vamos a volver al hilo principal, que todo esto ha venido a raiz de mejorar el repintado del juego. Con todos estos cambios ya tenemos separado el código que pinta el laberinto y el código que pinta al monigote... vamos al bucle del juego a ver cómo se puede acoplar todo esto.

Lo primero que deberíamos hacer es pintar el laberinto... después establecemos la posición inicial del jugador y, a continuación, pintamos el monigote en su sitio. No hay que perder de vista que ahora tenemos estructuras en vez de arreglos:

Código C++:
Ver original
  1. void cargar_laberinto(){
  2.  
  3.   int matriz[FILAS*COLUMNAS] ={...};
  4.  
  5.   DibujarLaberinto(matriz);
  6.  
  7.   PosicionJugador posicion;
  8.   posicion.actual.x = 1;
  9.   posicion.actual.y = 4;
  10.   PintarPosicion( posicion );

A continuación deberíamos actualizar el sistema que permite que el jugador se desplace por la pantalla. Si te fijas, en tu código estáis repitiendo las mismas comprobaciones en cada posible movimiento (izquierda, derecha, arriba y abajo). Yo creo que se puede simplificar bastante cambiando la perspectiva: calculamos la nueva posición (sea cual sea) y después verificamos si dicha posición es válida. Si resulta que la posición es válida actualizamos la posición del jugador y si no... no hacemos nada.

Para comprobar si la posición es válida lo suyo sería crear una nueva función. Por si no se nota, soy de la opinión de separar el código en porciones funcionales mínimas. Un ejemplo de la función podría ser la siguiente:

Código C++:
Ver original
  1. bool PosicionValida( Coordenadas posicion, int* matriz )
  2. {
  3.   return ( matriz[ posicion.x * COLUMNAS + posicion.y ] != 1 )
  4.       && ( matriz[ posicion.x * COLUMNAS + posicion.y ] != 2 );
  5. }

Es un código más bien sencillo, pero mejor separarlo... si es más óptimo prescindir de la función es algo que prefiero dejar en manos del compilador.

Y bueno, con esto ya podemos actualizar el código de movimiento:

Código C++:
Ver original
  1. while(posicion.actual.x != 17 || posicion.actual.y != 43)
  2.   {
  3.     if(kbhit())
  4.     {
  5.       Coordenadas nuevaPosicion = posicion.actual;
  6.  
  7.       int teclado = getch();
  8.       switch(teclado)
  9.       {
  10.         case LEFT:
  11.           nuevaPosicion.x--;
  12.           break;
  13.         case UP:
  14.           nuevaPosicion.y++;
  15.           break;
  16.         case RIGTH:
  17.           nuevaPosicion.x++;
  18.           break;
  19.         case DOWN:
  20.           nuevaPosicion.y--;
  21.           break;
  22.       }
  23.  
  24.       if( PosicionValida( nuevaPosicion, matriz ) )
  25.       {
  26.         posicion.actual = nuevaPosicion;
  27.         PintarPosicion( posicion );
  28.       }
  29.     }
  30.   }

Bueno, bonito y simple... ah no, espera, que faltaba declarar las dos constantes debajo de los includes:

Código C++:
Ver original
  1. const int FILAS = 24;
  2. const int COLUMNAS = 44;

Ahora ya sí. Prueba el programa ahora que no tiene que repintar el laberinto cada dos por tres a ver si se nota alguna mejoría :)

Un saludo