19 de diciembre de 2012

RGSS Básico - Capítulo 3 (b): Haciendo ventanas


Después de un largo tiempo y la retirada del blog de saranunu, continuaremos este tutorial. Posiblemente noten algún cambio en la forma de explicar las cosas porque este tutorial lo llevaba ella.

Continuemos donde lo dejamos: la construcción de una ventana.

Para la construcción de una ventana debemos de recordar varias cosas primero:
  • Heredar los atributos de Window_Base (importante).
  • Definir la clase con un nombre que no use otro script y que sea más o menos descriptivo de la función que va a cumplir dicha ventana.
  • Redactar lo más ordenadamente posible nuestro código. Este punto es importante no sólo para que nosotros podamos detectar errores fácilmente y para poder leer claramente el código, sino también para que otras personas sean capaces de leerlo también. Si somos ordenados con nuestro código y cometemos un error, por ejemplo, al escribir algeo, podremos detectarlo muy fácilmente. Además, si en un futuro queremos modificar el código o reutilizarlo para otra cosa, nos será mucho más simple y rápido poder hacer nuestro trabajo.
  • Utilizar comentarios. Este punto es muy importante y lo baso en mi experiencia programando. A veces creamos métodos o algoritmos y luego no recordamos bien qué pretendíamos hacer con ello o no recordamos cómo funcionaba. Para utilizar comentarios, utilizamos # y toda la línea de código que viene después se marcará en verde (indicando que es un comentario).
  • Revisar el código. Lamentablemente no tenemos un corrector de sintaxis en el editor de scripts del RPG Maker XP que nos indique si no hemos cerrado un método o un paréntesis, por ejemplo. Por eso nos toca ser cuidadosos y siempre revisar que todo esté en su sitio.
Ya de paso, si nos ocurriera algún error, os dejo unos puntos que, bajo mi experiencia, son siempre los más comunes y tontos:
  • Error de END. Posiblemente nos falte por cerrar algún método o bloque de código que utiliza un END (por ejemplo la estructura if, for o case) o tengamos más END de los que necesite el código (posiblemente porque hemos borrado alguna línea de código y se nos haya olvidado quitar el END).
  • Variables nil. Muchas veces nos olvidamos de declarar las variables al inicio y hacemos una operación con ella, quizá por ir precipitadamente o por no ser ordenados. También podemos utilizar una variable de método, por ejemplo, dentro de otro método, y para este otro método no existe; lo mismo que si llamamos una variable de un clase desde otra clase.
  • Se nos cuela un carácter. Sobre todo es común si copiamos código desde alguna web. Muchas veces las etiquetas que encierran el código expuesto en una web no son las adecuadas, o debido al funcionamiento y al código de la web interpreta algunos caracteres del script como otras cosas.
Es tiempo de comenzar a escribir. Abramos el editor del RPG Maker XP (F11) y creemos un nuevo espacio, siempre sobre Main para que sea leído por el Maker.

Del capítulo anterior tomemos el esqueleto de nuestra ventana:

class Window_Tuto < Window_Base #clase

   def initialize #se crea ventana
      super(x, y, ancho, alto)
      self.contents = Bitmap.new(width - 32, height - 32)
      refresh
   end

   def refresh #se dibuja contenido
       self.contents.clear
   end

end
POSICION Y TAMAÑO

Lo primero que debemos hacer es elegir una posición en la pantalla y el tamaño que va a tener la ventana. Para ello, tenemos que tener en cuenta que la pantalla del juego tiene una resolución como máximo de 640 píxeles de ancho y 480 píxeles.

Tanto la posición como el tamaño utiliza las unidades de píxeles y no de tiles.



Lo ideal es primero tener claro el tamaño de la ventana y después colocarla, para que después no nos quede cortada. Para esta prueba elegiremos la posición (0,0) y el tamaño (300, 250), sustituimos esos valores en super(x, y, ancho, alto)

super(0, 0, 300, 250)

Creamos un evento nuevo en un mapa cualquiera con su gráfico. Y ponemos en "Llamar script" la llamada a nuestra ventana:

@window = Window_Tuto.new

Cuando ejecutamos el juego y hablamos con nuestro evento aparecerá nuestra ventana.

Si juegas con los valores de super puedes ver resultados diferentes.

AÑADIR TEXTO

Podemos añadir texto a nuestra ventana de una forma simple:

self.contents.draw_text(x, y, ancho, alto, "texto")

Por supuesto, esta código debe ir en el método que dibujo el contenido de la ventana (principalmente, también se puede usar en métodos inventados por nosotros o en el update). Si recordamos, el método que dibuja los contenidos de una ventana es el refresh y toda línea de código debe ir debajo de self.contents.clear


Ahora veremos algo así:


Para cambiar el color de nuestro texto, podemos utilizar el comando: self.contents.font.color = system_color

Si vamos a Window_Base veremos que existe un método system_color que define de qué color será el texto que escribamos. Existen otros colores ya definidos en Window_Base:

  • normal_color: color por defecto de las letras (blanco).
  • disabled_color: se usa para opciones del menú que no están disponible, por ejemplo (gris).
  • system_color: para títulos o resaltar palabras (azul claro).
  • crisis_color: para estados y otros (amarilo).
  • knockout_color: para personajes muertos (rojo).
Podemos usar uno de los ya definidos o usar nuestro propio color a través de Color.new(Rojo, Verde, Azul, opacidad ). Si queremos saber qué valores poner para un color deseado, podemos utilizar el paint y en el selector de colores ver qué valores de Rojo, Verde y Azul poner para un color determinado.

La opacidad mide la transparencia de las letras. 255 es totalmente opaco y 0 es totalmente transparente.

Si queremos poner nuestra palabra en verde, por ejemplo usaremos:

self.contents.font.color = Color.new(30, 230, 0, 255)

Debido a la naturaleza del Ruby, el código que escribamos se va a ir leyendo en orden. Es decir, que se va leyendo desde la linea de arriba hacia abajo (como la mayoría de lenguajes de programación). Por eso debemos poner que se cambie el color del texto antes del comando de escribir.


Ahora todo el texto que pongamos debajo de esa línea se mostrará de ese color. Si queremos mostrar un texto de otro color bastará con volver a utilizar la línea de código de cambiar el color sobre la que escribe.

self.contents.font.color = normal_color
self.contents.draw_text(0, 32, 100, 32, "Hola que tal")

Fíjate que ahora la "y" del nuevo texto es mayor para colocarlo debajo del otro (+32 o +24, por ejemplo):


Al igual que el color, otros atributos se usan igual.
  • self.contents.font.name = "letra" - Sustituye letra por el nombre de la fuente a utilizar (tiene que estar instalada en el PC que corra el juego).
  • self.contents.font.size = num - Sustituye num por el número que representará el tamaño de la letra.
  • self.contents.font.bold = true/false - Pone las letras en negrita.
  • self.contents.font.italic = true/false - Pone las letras en cursiva.
En la ayuda del maker puedes encontrar más comandos y referencias, en Bitmap, y en el script Window_Base. También puedes añadir más cosas para la clase Bitmap y añadir comandos nuevos para tus ventanas. Por internet también hay métodos nuevos para esta clase. 

MOSTRAR OTROS DATOS

Vamos a ver cómo usar algunos métodos de Window_Base para poner más datos en nuestra ventana.

Tenemos por ejemplo: def draw_actor_name(actor, x, y)

Si usamos draw_actor_name, dibujaremos el nombre del actor. El actor es el un personaje del grupo. Pero no basta con poner sólo esa línea, si nos fijamos bien, requiere de varios parámetros que debemos indicar.

Algunos métodos necesitan que les indiquemos algunos parámetros para que funcionen. Lo sabremos porque éstos aparecerán entre paréntesis (...). En nuestro ejemplo, debemos de indicar el actor, x e y.

Veamos el código con detenimiento:

def draw_actor_name(actor, x, y)
    self.contents.font.color = normal_color
    self.contents.draw_text(x, y, 120, 32, actor.name)
end

Lo que realmente hace este método es escribir el nombre de actor (qué le hemos indicado) en las posiciones x e y que pusimos en los parámetros.

Es evidente que x e y van a hacer números, pero quizá actor no esté tan claro. Como dije antes, actor se refiere al actor de nuestro grupo de personajes, y no cualquier grupo, sino el equipo que va con nosotros en el juego (también conocido como party). Aunque también podríamos referirnos a un actor cualquiera que hemos creado en la Base de Datos, pero no de esta manera que voy a describir.

Para referirnos, por ejemplo, al primer actor, que es el que manejamos en el mapa, basta con referirnos a la variable global que guarda los actores del equipo en un array $game_party.actors[i]. La i se refiere a la posición que ocupa el actor en el equipo. Recordando que los arrays empiezan a contar desde 0, para referirnos al primer actor: $game_party.actors[0]



Como veis he declarado una variable de método para usarla dentro de la llamada a la función draw_actor_name, pero bien podría haber usado directamente la variable global $game_party.actors[0]. Es cuestión de cómo uno quiera hacer su código. A mí esto me servirá para escribir menos líneas de código, ya que si quiero referirme al mismo actor para otra cosa, sólo tengo que usar la palabra actor en vez de estar escribiendo lo otro.

LISTA DE VARIABLES GLOBALES EN RPG MAKER XP

Veamos otro ejemplo:

def draw_actor_level(actor, x, y)
   self.contents.font.color = system_color
   self.contents.draw_text(x, y, 32, 32, "Lv")
   self.contents.font.color = normal_color
   self.contents.draw_text(x + 32, y, 24, 32, actor.level.to_s, 2)
 end

Lo mismo, los parámetro a entregar son actor, x e y. Cómo veis, las funciones, o métodos, nos pueden ahorrar bastantes líneas de códigos si los usamos en otros scripts. Eso sí, recuerden que los métodos que queramos utilizar en nuestra clase deben pertenecer a la misma. En nuestro caso, utilizamos una clase para nuestra ventana, pero estamos usando métodos que pertenecen a otra clase distinta, sin embargo, recuerden que nuestra clase es "hija" de Window_Base, por lo tanto hereda TODOS sus atributos y podemos usar sin miedo sus métodos sin que ocurra un error.

Veamos cómo la variable actor.level tiene algo más puesto:
  • .to_s: convierte cualquier objeto a string (texto), ya que la función draw_text no puede trabajar con otro tipo de variable, ten en cuenta esto si quieres pintar el valor de una variable en tu ventana.
  • Un parámetro extra en draw_text: después de definir el string a dibujar, podemos añadir un parámetro opcional que indica la alineación del texto: 1 (centro) y 2 (derecha).
Otro método interesante es def draw_actor_hp(actor, x, y, width = 144). Cómo veis, uno de los parámetros  tiene un valor asignado en su declaración. Esto quiere decir que ese parámetro es opcional ponerlo (como la alineación en draw_text. Si por ejemplo ponemos draw_actor_hp(actor, 35, 50), automáticamente leerá que el ancho es 144 píxeles por defecto.

MOSTRAR IMAGENES

Para mostrar una imagen usaremos algo así como: variable= directorio_imagen. Declararemos una variable para guardar qué imagen queremos, y luego crearemos una especie de cuadro que es donde se dibujará la imagen.

Para esto, vamos a crear un nuevo método dentro de nuestro script.

def draw_picture(x, y, grap)

end

Para mostrar una imagen, debemos crear un nuevo objeto: un rectángulo. Definimos primero nuestra imagen (la metemos en una variable para trabajar más fácilmente).

bitmap = RPG::Cache.picture(grap)

Ojo, grap es el nombre de la imagen que debe estar en picture, debe ser un string. Hemos definido que grap sea un parámetro de nuestro método, así que cuando llamamos al método draw_picture acordaos de poner el nombre de la imagen entre "".

Creamos otra variable para crear nuestro rectángulo:

src_rect = Rect.new(0, 0, bitmap.width, bitmap.height)

Se pondrá en la posición 0,0 y tomará el ancho de nuestro gráfico. Para ponerlo todo junto y poder mostrarlo debemos crear un bloque que lo dibuje:

self.contents.blt(x, y, bitmap, src_rect)

Por lo que tenemos:

def draw_picture(x, y, grap)
  bitmap = RPG::Cache.picture(grap)
  src_rect = Rect.new(0, 0, bitmap.width, bitmap.height)
  self.contents.blt(x, y, bitmap, src_rect)
end

Como ves, el uso de variables ha dejado nuestro código más legible y ordenado.

Ahora pondremos esta imagen en la carpeta pictures de nuestro proyecto:


Y en nuestro método refresh añadiremos el comando de draw_picture con la posición y el nombre de la imagen. Donde "cara_heroe" es el nombre de nuestra imagen.

draw_picture(0,96,"cara_heroe") 


Regula los parámetros x e y (cuando llames al método), para colocar la imagen en donde desees.

Con este método tan sencillo que hemos creado, podrás utilizar cualquier imagen en tus ventanas. Puedes añadirlo en Window_Base para utilizarlo en todas tus ventanas sin tener que estarlo escribiendo en tu código.

En Window_Base ya existe un método para llamar a los gráficos de los charas (que es lo que usa el menú por defecto del maker): draw_actor_graphic(actor, x, y). Puedes usarlo para mostrar los charas en tus ventanas. Es parecido al que hemos creado, lo que hace es dividir el gráfico del chara para mostrar sólo la primera posición y no todas las posiciones del chara.

OPACIDAD

Podemos jugar con la opacidad de nuestra ventana con estos códigos (usarlos en def initialize):

self.opacity = 200 #opacidad de la ventana (no del contenido)
self.back_opacity = 200 #opacidad ventana pero no bordes
self.contents_opacity = 200 #opacidad del contenido

BORRAR VENTANA

Si no lo indicamos, nuestra ventana se creará y se quedará así permanentemente. Para borrar nuestra ventana es suficiente utilizando el comando: @window.dispose desde donde hayamos creado la ventana (¡¡no desde la clase de nuestra ventana!!). Recuerda dejar un poco de tiempo en el evento de donde llamamos la ventana antes de borrarla.

Esto llamará al método dispose de Window_Base y borrará la ventana.

Y hasta aquí el tutorial de Ventanas. A quedado más largo de lo planeado debido a que he querido tratar casi todas las cosas básicas que podemos dibujar en una ventana. En tutoriales posteriores, haremos ventanas más complejas y las usaremos en escenas (Scenes), además de ejemplos de menú y otras cosas.

ÍNDICE DE TUTORIALES DE RGSS:
  1. Conceptos básicos
  2. Hola Mundo en RGSS
  3. Haciendo ventanas (1)
  4. Haciendo ventanas (2)

ESTO ES UN TUTORIAL ORIGINAL NO COPIES, DISTRIBUYE Y ACREDITA A SUS VERDADEROS AUTORES

Creative Commons License

No hay comentarios:

Publicar un comentario

ATENCIÓN: Tu comentario aparecerá cuando sea aceptado.