Cita:
Iniciado por ALVIA2010 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 originalchar seguir;
do
{
cargar_laberinto();
gotoxy(52,7);cout<<"FELICIDADES...!!";
gotoxy(48,9);cout<<"1.-Recargar El juego..??"<<endl;
cin >> seguir;
} 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 originalstruct Coordenadas
{
int x;
int y;
Coordenadas( )
{ x = -1; y = -1; }
};
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 originalstruct PosicionJugador
{
Coordenadas actual;
Coordenadas antigua;
};
Con esto ya podríamos hacer la función que pinta el monigote:
Código C++:
Ver originalvoid PintarPosicion( PosicionJugador& posicion)
{
if( posicion.antigua.x >= 0 )
{
gotoxy( posicion.antigua.x, juego.antigua.y );
}
gotoxy( posicion.actual.x, posicion.actual.y );
posicion.antigua = posicion.actual;
}
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 originalvoid DibujarLaberinto(int matriz[][44]){
for(int i=0; i<24; i++){
for(int j=0; j<44; j++){
if(matriz[i][j] == 1) cout <<(char)176;
else if(matriz[i][j] == 2) cout <<(char)176;
else if(matriz[i][j] == 3) cout <<(char)187;
else if(matriz[i][j] == 4 ) cout <<(char)188;
else if(matriz[i][j] == 0) cout<<" ";
}
cout << endl;
}
}
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 originalvoid DibujarLaberinto(int* matriz)
{
char tiles[] = { ' ', (char)176, (char)176, (char)187, (char)188 };
for(int i=0; i < FILAS * COLUMNAS; i++, matriz++)
{
cout << tiles[ *matriz ];
if( (i+1) % COLUMNAS == 0 ) cout << endl;
}
}
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:
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 originalvoid cargar_laberinto(){
int matriz[FILAS*COLUMNAS] ={...};
DibujarLaberinto(matriz);
PosicionJugador posicion;
posicion.actual.x = 1;
posicion.actual.y = 4;
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 originalbool PosicionValida( Coordenadas posicion, int* matriz )
{
return ( matriz[ posicion.x * COLUMNAS + posicion.y ] != 1 )
&& ( matriz[ posicion.x * COLUMNAS + posicion.y ] != 2 );
}
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 originalwhile(posicion.actual.x != 17 || posicion.actual.y != 43)
{
if(kbhit())
{
Coordenadas nuevaPosicion = posicion.actual;
switch(teclado)
{
case LEFT:
nuevaPosicion.x--;
break;
case UP:
nuevaPosicion.y++;
break;
case RIGTH:
nuevaPosicion.x++;
break;
case DOWN:
nuevaPosicion.y--;
break;
}
if( PosicionValida( nuevaPosicion, matriz ) )
{
posicion.actual = nuevaPosicion;
PintarPosicion( posicion );
}
}
}
Bueno, bonito y simple... ah no, espera, que faltaba declarar las dos constantes debajo de los includes:
Código C++:
Ver originalconst int FILAS = 24;
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