Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Próxima revisión
Revisión previa
cursos:z88dk:avent2 [09-08-2007 13:50]
sromero creado
cursos:z88dk:avent2 [24-02-2020 20:23] (actual)
falvarez
Línea 1: Línea 1:
 +Publicado originalmente en [[https://magazinezx.speccy.org/08/z88dk.html|MagazineZX número 8]] (julio 2004)
  
-Creando una aventura conversacional con Z88DK (II)+====== Creando una aventura conversacional con Z88DK (II) ======
  
 Seguimos en esta ocasión por donde lo dejamos en la entrega anterior. Recordemos que el objetivo de esta serie de artículos es practicar con las funciones de texto de la librería z88dk, por medio de un ejemplo de programa que, aun siendo posible que se desarrolle con otras herramientas, como BASIC, parsers, etc., es bastante ilustrativo, y además nos permite estar haciendo un juego desde el primer momento. Seguimos en esta ocasión por donde lo dejamos en la entrega anterior. Recordemos que el objetivo de esta serie de artículos es practicar con las funciones de texto de la librería z88dk, por medio de un ejemplo de programa que, aun siendo posible que se desarrolle con otras herramientas, como BASIC, parsers, etc., es bastante ilustrativo, y además nos permite estar haciendo un juego desde el primer momento.
Línea 43: Línea 44:
     * Una antorcha, que podremos recoger en el callejón.     * Una antorcha, que podremos recoger en el callejón.
  
-De momento vamos a incluir la espada y la jarra en nuestra aventura. La antorcha es un tipo de objeto más complicado que trataremos más adelante. En el archivo aventura.c, en el método main, justo después de la inicialización de las habitaciones, podemos incluir el siguiente código (el código en rojo es el que se añade):+De momento vamos a incluir la espada y la jarra en nuestra aventura. La antorcha es un tipo de objeto más complicado que trataremos más adelante. En el archivo aventura.c, en el método main, justo después de la inicialización de las habitaciones, podemos incluir el siguiente código (el código marcado como "nuevo" es el que se añade):
  
 <code c> <code c>
 THabitacion habitaciones[6]; THabitacion habitaciones[6];
-TObjeto objetos[4];+TObjeto objetos[4];                      // nuevo
 inicializarHabitaciones(habitaciones); inicializarHabitaciones(habitaciones);
-inicializarObjetos(objetos);+inicializarObjetos(objetos);             // nuevo
 </code> </code>
  
Línea 69: Línea 70:
 (la antorcha todavía no la hemos creado... sí, somos pesados con la antorcha). El primer objeto es la espada, y al principio de la aventura se encontrará en la habitación cuyo identificador sea el 5 (la cocina); decimos al principio porque, como hemos comentado antes, eso puede cambiar. La espada tiene un peso de 5. El siguiente objeto es la jarra, cuya localización inicial es la -1, que hemos dicho que era la localización especial que usábamos para indicar que el objeto estaba en posesión del protagonista de la aventura. (la antorcha todavía no la hemos creado... sí, somos pesados con la antorcha). El primer objeto es la espada, y al principio de la aventura se encontrará en la habitación cuyo identificador sea el 5 (la cocina); decimos al principio porque, como hemos comentado antes, eso puede cambiar. La espada tiene un peso de 5. El siguiente objeto es la jarra, cuya localización inicial es la -1, que hemos dicho que era la localización especial que usábamos para indicar que el objeto estaba en posesión del protagonista de la aventura.
  
-El último paso es que, junto a la descripción de las habitaciones, se nos indiquen los objetos que podemos encontrar en ellas. Eso, evidentemente, es necesario hacerlo en la función escribirDescripcion, y se hará de forma similar a como se escribían las posibles direcciones; lo único es que tendremos que recorrer el array de objetos comprobando cuáles están en la habitación. Por lo tanto, tenemos que pasar como parámetro el array de objetos. La función podría quedar de la siguiente forma (el código en rojo es nuevo):+El último paso es que, junto a la descripción de las habitaciones, se nos indiquen los objetos que podemos encontrar en ellas. Eso, evidentemente, es necesario hacerlo en la función escribirDescripcion, y se hará de forma similar a como se escribían las posibles direcciones; lo único es que tendremos que recorrer el array de objetos comprobando cuáles están en la habitación. Por lo tanto, tenemos que pasar como parámetro el array de objetos. La función podría quedar de la siguiente forma (el código marcado como "Nuevo" es nuevo, además de la inclusión de "TObjeto objetos" en la definición de la función):
  
 <code c> <code c>
-void escribirDescripcion(THabitacion habitaciones, int habitacion, TObjeto objetos)+void escribirDescripcion(THabitacion habitaciones, int habitacion, TObjeto objetos )
 { {
  int hayObjetos = 0;  int hayObjetos = 0;
Línea 90: Línea 91:
  printf("\n\n");  printf("\n\n");
  
 +        // Nuevo (principio)
  printf("En la habitacion puedes ver:");  printf("En la habitacion puedes ver:");
  for (i=0;i<4;i++)  for (i=0;i<4;i++)
Línea 99: Línea 101:
  if (hayObjetos == 0)  if (hayObjetos == 0)
  printf(" nada");  printf(" nada");
 +        // Nuevo (fin)
  
  printf("\n\n");   printf("\n\n");
Línea 112: Línea 115:
 El código que hemos añadido recorre el array de objetos comprobando para cada uno si su localización corresponde con el identificador de la habitación actual. En el caso de que sea así escribe su nombre (fíjate en el espacio en blanco antes del %s). La variable hayObjetos nos sirve para determinar si hay algún objeto en la habitación. En un principio vale 0, y si la localización de algún objeto se corresponde con el identificador de la habitación actual, valdrá 1. Solo en el caso de que valga 0 se mostrará el mensaje "nada". Ahora ya podemos compilar y ejecutar la aventura, dirigiéndonos hacia la cocina para comprobar que la espada está allí. No podemos saber nada de la jarra, porque todavía no hemos implementado el inventario, lo haremos en la siguiente sección. El código que hemos añadido recorre el array de objetos comprobando para cada uno si su localización corresponde con el identificador de la habitación actual. En el caso de que sea así escribe su nombre (fíjate en el espacio en blanco antes del %s). La variable hayObjetos nos sirve para determinar si hay algún objeto en la habitación. En un principio vale 0, y si la localización de algún objeto se corresponde con el identificador de la habitación actual, valdrá 1. Solo en el caso de que valga 0 se mostrará el mensaje "nada". Ahora ya podemos compilar y ejecutar la aventura, dirigiéndonos hacia la cocina para comprobar que la espada está allí. No podemos saber nada de la jarra, porque todavía no hemos implementado el inventario, lo haremos en la siguiente sección.
  
-¿Quién se habrá dejado esta espada aquí tirada en la cocina? +{{ cursos:z88dk:z88dk4_1.png |¿Quién se habrá dejado esta espada aquí tirada en la cocina?}} 
-¿Quién se habrá dejado esta espada aquí tirada en la cocina?+ 
  
  
Línea 120: Línea 124:
 A partir de este momento, el secreto para poder realizar acciones con los objetos durante la aventura consiste nada más que en añadir posibles frases a usar por el jugador en el intérprete de comandos. Si recordamos, el intérprete de comandos era la parte del código que leía la cadena de texto introducida por el jugador y comparaba con el vocabulario conocido con el programa. Para incluir los comandos de inventario y coger y dejar objetos debemos añadir código a esta parte. A partir de este momento, el secreto para poder realizar acciones con los objetos durante la aventura consiste nada más que en añadir posibles frases a usar por el jugador en el intérprete de comandos. Si recordamos, el intérprete de comandos era la parte del código que leía la cadena de texto introducida por el jugador y comparaba con el vocabulario conocido con el programa. Para incluir los comandos de inventario y coger y dejar objetos debemos añadir código a esta parte.
  
-Implementemos primero el inventario. Cuando el jugador teclee "inventario" o "i", se deberán mostrar por pantalla todos los objetos que porta. Podemos añadir el siguiente código al intérprete de comandos, dentro del método main (el código en rojo es el que se ha añadido):+Implementemos primero el inventario. Cuando el jugador teclee "inventario" o "i", se deberán mostrar por pantalla todos los objetos que porta. Podemos añadir el siguiente código al intérprete de comandos, dentro del método main:
  
 <code c> <code c>
Línea 127: Línea 131:
  printf("\n\nNo puedo ir en esa direccion\n\n");  printf("\n\nNo puedo ir en esa direccion\n\n");
  }  }
 +
 +        // Nuevo (principio)
  else if (strcmp(comando,"i") == 0 || strcmp(comando,"inventario") == 0)  else if (strcmp(comando,"i") == 0 || strcmp(comando,"inventario") == 0)
  {  {
Línea 141: Línea 147:
  printf("\n\n");   printf("\n\n");
  }  }
 +        // Nuevo (fin)
  
  else  else
Línea 150: Línea 157:
 La variable hayObjetos se debe definir al comienzo de la función main y cumple el mismo objetivo que en la función describirHabitacion. Lo único que se hace en el caso del inventario es recorrer el array de objetos escribiendo el nombre de aquéllos para los que el valor de localización sea -1, o "nada" en el caso de que no haya ninguno que cumpla esta condición. Si compilamos y ejecutamos, por fin veremos la jarra en nuestro juego al teclear "i" o "inventario". La variable hayObjetos se debe definir al comienzo de la función main y cumple el mismo objetivo que en la función describirHabitacion. Lo único que se hace en el caso del inventario es recorrer el array de objetos escribiendo el nombre de aquéllos para los que el valor de localización sea -1, o "nada" en el caso de que no haya ninguno que cumpla esta condición. Si compilamos y ejecutamos, por fin veremos la jarra en nuestro juego al teclear "i" o "inventario".
  
-Esperemos que esta jarra nos sirva de algo en nuestra aventura +{{ cursos:z88dk:z88dk4_2.png |Esperemos que esta jarra nos sirva de algo en nuestra aventura}} 
-Esperemos que esta jarra nos sirva de algo en nuestra aventura+
  
-Para que el jugador pueda coger y dejar objetos, lo único que tenemos que hacer, nuevamente, es añadir los comandos adecuados al intérprete de comandos. La implementación es tan simple como hacer que cuando cojamos un objeto, la localización del mismo pase a ser -1, y que cuando dejemos un objeto, la localización del mismo pase de ser -1 a ser el identificador de la habitación actual. Veamos primero cómo implementar la parte de coger objetos (el código en rojo es código añadido):+Para que el jugador pueda coger y dejar objetos, lo único que tenemos que hacer, nuevamente, es añadir los comandos adecuados al intérprete de comandos. La implementación es tan simple como hacer que cuando cojamos un objeto, la localización del mismo pase a ser -1, y que cuando dejemos un objeto, la localización del mismo pase de ser -1 a ser el identificador de la habitación actual. Veamos primero cómo implementar la parte de coger objetos:
  
 <code c> <code c>
Línea 170: Línea 177:
  printf("\n\n");   printf("\n\n");
 } }
 +// Nuevo (principio)
 else else
 // Comandos con más de una palabra // Comandos con más de una palabra
Línea 201: Línea 209:
  printf("\n\nNo entiendo lo que dices\n\n");  printf("\n\nNo entiendo lo que dices\n\n");
 } }
 +// Nuevo (fin)
 </code> </code>
  
Línea 219: Línea 228:
 Obsérvese que, tanto si el objeto existe como si no, tanto si el objeto está en la misma habitación como si no, se muestra el mismo mensaje de error ("No puedo hacer eso"). Esto es básico para no darle pistas al jugador sobre los objetos que existen en nuestro juego. Obsérvese que, tanto si el objeto existe como si no, tanto si el objeto está en la misma habitación como si no, se muestra el mismo mensaje de error ("No puedo hacer eso"). Esto es básico para no darle pistas al jugador sobre los objetos que existen en nuestro juego.
  
-El código para dejar objetos es prácticamente igual; la única diferencia es que comprobamos que para dejar un objeto éste se encuentre en el inventario (localizacion = -1) y que dejar un objeto significa cambiar el valor del campo localizacion al del identificador de la habitación actual (el código en rojo es el que se ha añadido):+El código para dejar objetos es prácticamente igual; la única diferencia es que comprobamos que para dejar un objeto éste se encuentre en el inventario (localizacion = -1) y que dejar un objeto significa cambiar el valor del campo localizacion al del identificador de la habitación actual:
  
 <code c> <code c>
Línea 226: Línea 235:
  }  }
  }  }
 +        // Nuevo (principio)
  else if (strcmp(comando,"dejar") == 0)  else if (strcmp(comando,"dejar") == 0)
  {  {
Línea 250: Línea 260:
  }  }
  }  }
 +        // Nuevo (fin)
  else  else
  printf("\n\nNo entiendo lo que dices\n\n");  printf("\n\nNo entiendo lo que dices\n\n");
Línea 276: Línea 287:
 </code> </code>
  
-Para resolver el segundo punto, añadimos el siguiente código a la hora de manejar que el jugador coja objetos (código en rojo):+Para resolver el segundo punto, añadimos el siguiente código a la hora de manejar que el jugador coja objetos:
  
 <code c> <code c>
Línea 282: Línea 293:
 </code> </code>
  
-Y para el tercer punto introducimos el siguiente código (la línea en rojo):+Y para el tercer punto introducimos el siguiente código:
  
 <code c> <code c>
Línea 301: Línea 312:
  hayObjetos = 1;  hayObjetos = 1;
  
 +                        // Nuevo (principio)
  if (objetos[i].peso + pesoTransportado <= 6)  if (objetos[i].peso + pesoTransportado <= 6)
  {  {
Línea 309: Línea 321:
  else  else
  printf("\n\nNo puedo transportar mas peso\n\n");  printf("\n\nNo puedo transportar mas peso\n\n");
 +                        // Nuevo (Fin)
  
  i++;  i++;
Línea 402: Línea 415:
  printf("\n\n");   printf("\n\n");
 } }
 +// Nuevo (principio)
 else if (strcmp(comando,"coger una antorcha") == 0) else if (strcmp(comando,"coger una antorcha") == 0)
 { {
Línea 447: Línea 461:
 } }
 else else
 +// Nuevo (Fin)
  
 // Comandos con más de una palabra // Comandos con más de una palabra
Línea 485: Línea 500:
 </code> </code>
  
-La antorcha en acción +{{ cursos:z88dk:z88dk4_3.png |La antorcha en acción}} 
-La antorcha en acción+
  
 ===== Resumen ===== ===== Resumen =====
Línea 505: Línea 520:
  
 Por último, una curiosidad que el autor de este texto ha podido comprobar mientras realizaba este tutorial; el tema de las violaciones de segmento, con respecto a las cadenas. Por lo que se ha visto hasta ahora, no parece producirse una violación de segmento en ejecución si hay algún problema de memoria con punteros que se nos escape; simplemente se mostrarán caracteres extraños por pantalla... además, ¿cómo sería una violación de segmento en un Spectrum? ¿Similar a un RANDOMIZE USR 0? Por último, una curiosidad que el autor de este texto ha podido comprobar mientras realizaba este tutorial; el tema de las violaciones de segmento, con respecto a las cadenas. Por lo que se ha visto hasta ahora, no parece producirse una violación de segmento en ejecución si hay algún problema de memoria con punteros que se nos escape; simplemente se mostrarán caracteres extraños por pantalla... además, ¿cómo sería una violación de segmento en un Spectrum? ¿Similar a un RANDOMIZE USR 0?
 +
  
 ===== Enlaces ===== ===== Enlaces =====
  
  
-    * [[http://www.speccy.org/magazinezx/revistas/8/src/fuentes.tar.gz|Archivos fuente del ejemplo propuesto]+    * [[https://magazinezx.speccy.org/08/src/fuentes.tar.gz|Archivos fuente del ejemplo propuesto]]