GUÍA DE RUBY en base a
RPG MAKER XP (RGSS) por Ánemus
-2-
Prólogo Este tutorial está dedicado a todos aquellos que quieran iniciarse en el mundo de la programación en Ruby orientado a RPG Maker XP, o lo que también es llamado RGSS (Ruby Game Scripting System: Sistema de Programación para Juegos en Ruby). Antes de poner los contenidos aviso dos cosas: La primera, que esto no es una guía exhaustiva de programación en RGSS, y que es posible que contenga errores, por lo cual, tras terminar de leer esta guía recomendaría mirar códigos para comprender mejor las cosas. La segunda es que no le resulta igual de fácil a todo el mundo programar, así que, si pasa el tiempo y no consiguen nada, no se desesperen, la constancia casi todo lo puede. A todos aquellos que, al intentar programar ven una página de códigos y no comprenden, les comunico que Ruby es un lenguaje de programación de nivel alto, y por tanto es muy similar al lenguaje humano. Como casi todos los lenguajes de programación, se basa en el inglés para sus comandos, por lo que, unos básicos conocimientos de inglés nos ayudarán. De todas maneras, en este tutorial se explica que significa, traducido al español, los comandos de habla inglesa. Por último, comentarles que la programación es un sistema muy bueno de potenciación del cerebro, ayuda a la ramificación del mismo y a mejorar sus interconexiones. Es decir, mejora su funcionamiento y potencia la velocidad de pensamiento. Ahora comienzo con el tutorial, les deseo suerte con su aprendizaje. Si tienen alguna duda, contacten conmigo desde esta página (bien desde los foros o desde la sección contacta de la misma). http://anemusint.byethost7.com/ Gracias por confiar en este tutorial,
Ánemus
-3-
Índice 1. 2. 3. 4.
Introducción ....................................................................................................... Pág. 4 Entender el Sistema de colores del editor......................................................... Pág. 4 Operadores matemáticos .................................................................................. Pág. 4 Variables............................................................................................................ Pág. 5 4.1. Introducción................................................................................................. Pág. 5 4.2. Tipos según su duración ............................................................................. Pág. 5 4.3. Números...................................................................................................... Pág. 6 4.4. Textos.......................................................................................................... Pág. 6 4.5. Booleanos ................................................................................................... Pág. 7 4.6. Arrays .......................................................................................................... Pág. 8 4.7. Tablas (Hash Tables).................................................................................. Pág. 8 4.8. Objetos ........................................................................................................ Pág. 8 5. Print ................................................................................................................... Pág. 9 6. Gráficos ............................................................................................................. Pág. 10 6.1. Sprites ......................................................................................................... Pág. 10 6.2. Incrustados en ventanas ............................................................................. Pág. 11 6.3. Puntos y Líneas .......................................................................................... Pág. 12 7. Condicionales .................................................................................................... Pág. 13 7.1. If .................................................................................................................. Pág. 13 7.2. Unless ......................................................................................................... Pág. 14 7.3. Case ............................................................................................................ Pág. 14 8. Bucles ................................................................................................................ Pág. 15 8.1. For ............................................................................................................... Pág. 15 8.2. Next ............................................................................................................. Pág. 15 8.3. Loop do ....................................................................................................... Pág. 16 8.4. Break .......................................................................................................... Pág. 16 8.5. While ........................................................................................................... Pág. 16 9. Operadores lógicos > And Or Not ..................................................................... Pág. 17 10. Números Aleatorios ........................................................................................... Pág. 18 11. Clases................................................................................................................ Pág. 20 11.1. Introducción................................................................................................. Pág. 20 11.2. Definición de clases y llamada.................................................................... Pág. 20 11.3. Métodos de clase ........................................................................................ Pág. 20 11.4. Parámetros en los métodos de clase.......................................................... Pág. 21 11.5. Superposición de métodos de clase ........................................................... Pág. 21 11.6. Fórmulas de acceso a variables de una clase (attr) ................................... Pág. 22 11.7. Superposición de clases ............................................................................. Pág. 22 11.8. Alias............................................................................................................. Pág. 22 11.9. Subordinación de clases ............................................................................. Pág. 23 11.10. Clases-Ventana (Windows) ..................................................................... Pág. 24 11.11. Clases-Ventanas de comandos (Window_Selectables).......................... Pág. 25 11.12. Clases-Escena (Scenes) ......................................................................... Pág. 26 12. Clases más importantes ....................................................................................... Pág. 28 12.1. Window_Base ............................................................................................. Pág. 28 12.2. Interpreter.................................................................................................... Pág. ?? 12.3. Scene’s ...................................................................................................... Pág. ?? 12.4. Window’s .................................................................................................... Pág. ?? 12.5. Game’s ........................................................................................................ Pág. ?? 12.6. Main (no es una clase)................................................................................ Pág. 29
-41. Introducción El sistema de programación del RPG Maker XP es Ruby, y se encuentra en los llamados scripts. Para acceder a los scripts pulsa F11 durante la edición del juego, para que te salga la pantalla de scripts. A la derecha están las páginas, y a la izquierda los contenidos de las mismas. Las páginas no son necesarias, pero, para mayor orden se recomienda que vaya una clase por página (ya explicaré que es eso de clases), y que dicha página lleve el nombre de la clase, auque no es necesario, pero ayuda a encontrar cosas. El Ruby es un lenguaje de programación orientado a objetos, es decir, que usa objetos para funcionar. Este sistema es uno de los más rápidos, ya que hace que haya menos líneas de código haciendo que no sean necesarias las definiciones de variables (más abajo explicadas) y algunas otras cosas. Ruby posee la función de la identificación de mayúsculas y minúsculas, por lo que podemos definir una variable @hola, y otra @HOLA, que serán distintas. También sucede con los comandos. No reconocerá IF, ni If, ni iF, pero si if. Los comandos siempre en minúscula a no ser que se especifique lo contrario.
2. Entender el sistema de colores del editor Azul oscuro: definiciones, clases y operadores lógicos (if, for, case…), las referencias a objetos self, super y el valor nulo nil, y las constantes booleanas true y false NO ADMITEN MAYÚSCULAS. De todas maneras, ningún comando que se explique en este tutorial que vaya con minúsculas se aceptará con mayúsculas. Hay unos pocos comandos que llevan mayúsculas, y solo serán reconocidos con esas mayúsculas. Granate: números Azul claro: operadores matemáticos, puntos, paréntesis… Verde: Reminders, notas, no se ejecutan, sirven para que lo leas, como anotaciones para decir que aquí va algo, y que es. Se ponen con # Morado (entre comillas): Son textos. Se usan para las variables de texto (string), imprimir mensajes, el nombre de archivos… Negro: Nombres de variables, clases, definiciones, propiedades de clases, y el comando print (para mandar mensajes de error) Hay muchas palabras nuevas…no se desanimen, se explicarán.
3. Operadores matemáticos Son utilizados en las operaciones matemáticas. Suelen ser parecidos a nuestra forma de expresar las matemática. • + : signo de suma • - : signo de resta • * : signo de multiplicación • / : signo de división • ** : signo de potenciación • % : signo de resto de división
-5-
Hay algunas operaciones que no están disponibles de forma tan simple, como el porcentaje o la raíz. Ahora vienen explicadas: • Raíz: se usa la potenciación de la siguiente manera: num** (1/raiz), siendo raiz el valor del exponente de la raiz que deseamos hacer (raíz cuadrada 2, raíz cúbica 3… • Porcentaje: se multiplica el valor por el número del porcentaje que se desea obtener, y se divide por cien (num* porcentaje/100). También hay formas de abreviar algunas operaciones. Por ejemplo, estamos dando a una variable num su mismo valor sumándole 5, pues se escribiría de esta manera siguiendo el código normal: :: Códigos :: num = num + 5 Pero se puede abreviar en la siguiente sentencia: :: Códigos :: num += 5
Ruby también tiene la opción de usar decimales, solo se ha de añadir a uno de los términos de la operación matemática, una coma y tantos ceros como decimales quieres que use. Recomiendo no pasarse con los ceros.
4. Variables 4.1 Introducción Las variables de Ruby, son auto definidas (no hay que definirlas) y su tipo de valor es variable (igual pueden contener un número como un booleano (true, false)). A pesar de que sean variantes, no se puede decir, ahora eres de texto, ahora de número, para ello hay que definirlas nulas (vaciarlas /formatearlas) con la sentencia siguiente: :: Códigos :: variable = nil Es preferible no usar mayúsculas (se puede) pero si usas mayúsculas y luego te refieres a la variable sin dichas mayúsculas, no funciona. Es decir: si tú defines la variable Hola, y te refieres a ella mas tarde como hola, no funcionará.
4.2 Tipos según su duración Hay tres tipos de variables en orden a su duración: • Globales: se inician cuando son llamadas por primera vez, y se terminan cuando se cierra el programa. Se usarían para variables que no queremos que pierdan nunca su valor mientras el juego esté activo. Para que el valor se guarde en un archivo se usará una sentencia que explicaré mas tarde. Se diferencian en que son introducidas por el símbolo del dólar $.
-6• De Clase: se inician cuando son llamadas, y se terminan cuando la clase donde fueron llamadas se termina o vacía. Se diferencian en que son introducidas por el carácter del arroba @. • De Método: se inician cuando el método se inicia, y se terminan cuando se sale del método. No funcionan fuera de dicho método. No van introducidas por ningún carácter.
4.3 Números Las variables numéricas se caracterizan por contener un número. Puede ser un entero desde unos 2 billones a menos ese mismo número. Pero también puede tener comas. Para definir una variable numérica has de darle un valor numérico a una variable liberada (cuyo valor es nil o no ha sido definida (según su nivel (global, de clase o de método)) :: Códigos :: num = 5
OPERACIONES :: Códigos :: m = 1 m += 1
#=>equivale a m = m + 1
m -= 1
#=>m =
m *= 2
#=>m = m * 2
m /= 2
#=>m = m / 2 -> 1
m – 1 -> 1 -> 2
Métodos .chr: devuelve al carácter ASCII correspondiente al número Para ver el código ASCII puedes hacerlo http://ascii.cl/es/. .empty? : devuelve true si la variable está vacía. .to_s: lo convierte en una cadena de texto.
4.4 Textos Las variables String contienen una cadena de texto. :: Códigos :: #esta variable string no contiene texto, pero es de texto @variablestring1 = “” #esta variable string contiene un texto @variablestring2 = “¡Hola a todos!”
No puedes convertir directamente una variable de número en una de texto, para ello usa la siguiente sentencia:
-7-
:: Códigos :: #esta es una variable de número @numero = 10 #esta es una variable de texto @texto = “#{@numero}” #esta variable tendrá el valor del triple de @número @texto = “#{@numero *3}” Para unir dos variables de texto se usa el comando + entre las dos variables a sumar. :: Códigos :: str1 = “Hola, ” str2 = “¿Qué tal?” #esta variable de texto contendrá la unión de las cadenas de #texto str1, y str2. @texto = str1 + str2 #ahora @texto contiene “Hola, ¿Qué tal?”
Métodos .size: nos devuelve el número de caracteres que tiene la cadena. .upcase: las letras se muestran mayúsculas. .downcase: las letras se muestran en minúsculas. .gosub (patrón) {comando}: busca un patrón en el texto y ejecuta un comando. .insert (caracter, inserción): inserta un texto tras el carácter seleccionado. .empty? : devuelve true si la variable está vacía. .include? (string): devuelve true si la cadena string está en el texto donde se aplica este método. .delete (string): elimina una cadena de texto string del texto donde se aplica este método.
4.5 Booleanos Son variables que sólo pueden adquirir 2 valores: true (verdadero, si, 1) o false (falso, no, 0). Su nombre viene de un matemático llamado Boole, que inventó una rama de las matemáticas que se dedica a estudiar si es verdad o no. Se emplean con el llamado álgebra de boole, que aunque no es necesario conviene conocer. Se emplea con ceros y unos (como si fuera binario) pero aquí, para evitar líos voy a sustituir el cero por el false y el uno por el true. Propiedades básicas de álgebra de boole: • Suma: true + false = true; true + true = true; false + false = false • Multiplicación: true * false = false; true * true = true; false * false = false • Negación: true (negado) = false; false (negado) = true El álgebra de boole es algo más extenso y complicado, pero ocuparía demasiado para incluirlo aquí. Mas adelante esto será bastante útil, cuando veamos los condicionales.
-84.6 Arrays Son variables excepcionales que pueden contener más de un valor en su interior. Para poder usarlas hay que definirlas como arrays con: :: Códigos :: array = [ ] #dentro de los corchetes pueden entrar algunas #ordenes como estas, #pero no es necesario para definirla. array2 = [“hola”, “¿qué tal?”, “adiós”]
Los arrays pueden contener objetos también. Y como cosa excepcional, pueden contener más de un tipo de valor: :: Códigos :: array3 = [“hola”, 10, true] Métodos .clear: vacía la variable. .compact: al usarlo junto a la variable, devuelve el Array sin espacios vacíos .compact: borra todos los espacios vacíos. .include? () busca un valor u objeto situado en los paréntesis. Devuelve un true o un false. .push(): incluye como último elemento del array lo que halla en los paréntesis.
4.7 Tablas (Hash Tables) También llamados Arrays Asociativos, este tipo excepcional de array permite relacionar una clave con un valor, en vez del índice de los Arrays. Para poder usar un array asociativo necesitamos definirlo como tal añadiéndole una clave con su valor o diciendo que queremos que sea un array asociativo. :: Códigos :: hash = { } #dentro de las llaves pueden entrar algunas #asociaciones, pero no es necesario para definirla. array2 = {“Valor 1”=>12, “Valor 2”=>3} # el vínculo de asociación es => La llamada a los valores de un array asociativo se realiza de la siguiente manera: :: Códigos :: print hash [“Valor 1”] # Mostrará 12 print hash [“Valor 2”] # Mostrará 3 print hash [“Hola”] # Mostrará nil Métodos: .delete (string): elimina la clave que equivalga al valor del parámetro, y con ella su valor. .keys: devuelve un array normal con las claves. .values: devuelve un array normal con los valores.
-9-
4.8 Objetos Las variables también pueden contener objetos, los cuales se definen en clases (class). Hay una serie de variables objeto globales muy importantes en el desarrollo del juego y que deben de ser conocidas para su correcta utilización: • $scene: contiene la clase de escena que se muestra en el preciso instante. Si por ejemplo estamos en el menú de objetos, la variable $scene contendrá el objeto Scene_Items. • $data_actors: contiene a los actores o personajes principales del juego. • $data_items: contiene los datos de los objetos utilizables. • $data_weapons: contiene los datos de las armas. • $data_armors: contiene los datos de los protectores y accesorios. • $data_skills: contiene los datos de las habilidades. • $data_animations: contiene los datos de las animaciones. • $data_troops: contiene los datos de los grupos de enemigos. • $data_classes: contiene los datos de las profesiones. • $data_enemies: contiene los datos de los enemigos. • $data_states: contiene los datos de los estados. • $data_tilesets: contiene la información de los tiles. • $data_comon_events: contiene la información sobre los eventos comunes. • $data_system: contiene la información del sistema. :: Notas :: Todos las variables globales $data se cargan en el método main de la clase Scene_Title, y hay que mencionar que no son objetos simples, si no arrays que contienen objetos. De tal manera que si queremos acceder a uno tendremos que poner su index. También mencionar que las variables $data_... contienen puramente datos. • $game_system: contiene la clase Game_System, contiene variables del sistema. • $game_temp: contiene la clase Game_Temp, contiene variables temporales, como el formato de batalla u otras cosas. • $game_switches: contiene la clase Game_Switches, contiene los interruptores del juego. Se accede a ellos de la siguiente manera: $game_switches[id] = true. Como veis, es un Array. • $game_variables: contiene la clase Game_Variables, que contiene las variables numéricas del juego. Se accede a ellas de idéntica manera que los interruptores. Es un Array. • $game_self_switches: contiene la clase Game_SelfSwitches, que contiene los valores de los interruptores locales. Es un Array. • $game_screen: contiene la clase Game_Screen, que contiene la pantalla a mostrar, así como las imágenes, los efectos de clima, el tono... • $game_actors: contiene la clase Game_Actors, que contiene los datos de los actores que están en el grupo. Es un Array. Cada uno de los índices de esta variable son el código de la clase Game_Actor. • $game_party: contiene la clase Game_Party, que incluye los cuatro personajes que tiene el grupo, y otras características del grupo, tales como el oro, los objetos, los pasos, los protectores... • $game_troop: contiene la clase Game_Troop, en la cual se incluyen llamadas a la clase Game_Enemy, y que contiene las características de los grupos de enemigos o tropas. • $game_map: contiene la clase Game_Map, en la cual se incluyen las opciones de los mapas. • $game_player: contiene la información escrita en Game_Player, y esta contiene las características del personaje principal. :: Notas :: Todas estas variables se definen en el método command_new_game de Scene_Title, y se pueden modificar en las páginas de códigos de la parte de arriba.
- 10 -
En el fondo, los tipos de variables que estudiamos antes son también objetos.
5. Print Este comando sirve para enviar un cuadro de mensaje con un texto que definiremos después: :: Códigos :: print “Buenos días!” Eso mostrará un mensaje que dice Buenos días!. También podemos hacer que muestre cualquier variable, sea del tipo que sea. :: Códigos :: booleano = true print booleano numero = 12 print numero texto = “hola” print texto
#=> true #=> 12 #=>hola
Esto último, es especialmente útil en la fase de desarrollo de un script, ya que sería la única manera de mostrar valores de forma clara, pero cuidado con ponerlo en un método update, pues se repetirá eternamente si no ponéis un límite. Si intentáis hacer print con una variable de objeto, os mostrará la almohadilla, el nombre del objeto y una serie de valores. Existe una variante de Print llamada p, pero muestra las comillas.
6. Gráficos 6.1 Sprites Para mostrar gráficos, primero tenemos que definir una variable como un objeto bitmap, o Sprite, lo que no es más que una variable objeto. :: Códigos :: @imagen = Sprite.new Tras ello, hay que definir que sprite o imagen queremos que muestre. Para eso usamos lo siguiente: :: Códigos :: @imagen.bitmap = ("Graphics/subcarpeta/archivo.png")
- 11 Donde pone subcarpeta hay que poner la carpeta donde se aloja. Si es un battler, la carpeta será Battlers. Donde pone archivo irá el nombre del archivo. Hay una forma más rápida que es usando la sentencia RPG::Cache que funciona de la siguiente manera. Se aplica sobre la propiedad bitmap del sprite que antes definimos. Tras poner RPG::Cache (son dos veces dos puntos) añadimos un punto, y el nombre de la carpeta con minúsculas y en singular (quitando la s), y tras esto, entre paréntesis y con comillas, el nombre del archivo sin la extensión. :: Códigos :: @imagen.bitmap = RPG::Cache.battler("002-Fighter02") La ventaja de usar sprites, es que se pueden colocar en cualquier parte de la pantalla, y modificar su posición con x e y (@imagen.x y @imagen.y), y con los métodos ox y oy podemos definir el origen de la imagen (que punto de la imagen es donde se aplica que x se igual a la posición dada). Son por tanto para escenas, como fondos e imágenes independientes. (el fondo del title es un Sprite, los battlers se usan como objetos sprite...). Esto no es lo mismo si usamos de otra manera los gráficos.
6.2 Gráficos incrustados en ventanas Si necesitamos un gráfico que se muestre dentro de una ventana, y si esta se mueve, que el también se mueva, necesitamos incrustarlos. Para ello existen los Rectángulos (llamados rect). Primero definimos la imagen, no como sprite, sino como imagen dependiente:
:: Códigos :: im = RPG::Cache.battler("003-Fighter03") Tras esto, la imagen no se mostrará, para que se muestre necesitamos crear un rectángulo donde aparecerá la imagen. Con este sistema podemos seleccionar un cacho de la imagen que deseamos ver, sin tener que verla entera. Se usa con los Characters, por ejemplo en algunos menús de guardado, que mediante una operación matemática, hacen que se mueva. El código del Rectángulo es el siguiente (recomiendo que el rectángulo sea una variable corta):
:: Códigos :: src_rect = Rect.new(picx, picy, ancho, alto) Donde pone picx, irá la coordenada x desde donde aparecerá la imagen, en picy, la coordenada y donde aparecerá la imagen, y en ancho y alto el ancho y el alto. Cuando digo la coordenada donde aparecerá la imagen, significa algo así como, si tenemos una imagen de 48x48, dividida en 4 sectores de 24x24, y queremos mostrar la de abajo a la izquierda, el picx será 24, el picy será 0 y el ancho y el alto serán 24. El último paso es mostrar la imagen dentro del rectángulo:
- 12 :: Códigos :: self.contents.blt(x, y, im, scr_rect, opacidad) En x irá la coordenada x donde se mostrará el rectángulo con la imagen dentro, en y la coordenada y, en im se pone la variable de la imagen, en scr_rect se pone el Rect que definimos antes (se puede poner como variable src_rect o como definición Rect.new(24, 0, 24, 24)# esto es el ejemplo de antes) y por último, en opacidad irá la opacidad, en un número de 8 bits (del 0 al 255), siendo 255 el máximo de opacidad, y 0 la invisibilidad. Si no ponemos nada en este último parámetro, se usará el valor 255, es decir, opaco.
6.3 Puntos y líneas Poner un punto es fácil, y una línea es igual. El comando es este: :: Códigos :: self.contents.fill_rect (x, y, ancho, alto, color, opacidad) De esta manera con la x y la y, definimos la posición del rectángulo relleno, que es lo que significa fill_rect; con el ancho y el alto definimos la altura y la anchura del rectángulo (un punto tiene ambos valores en 1); el color se define así: :: Códigos :: Color.new =(red, green, blue, opacity) #Red=rojo, Green=verde, Blue=azul. #la opacidad es opcional, si no se pone adoptará el valor 255 (opaco) Y por ultimo queda la opacidad. Esta, como siempre, es opcional, y si no se pone adoptará el valor 255 (opaco). Para poner un punto, ancho y alto tienen que ser 1, el. Para hacer una línea, uno de los dos ha de ser más de 1 y el otro 1. Si le damos a los dos un valor superior a 1, nos saldrá un rectángulo. Para hacer una línea inclinada, habrá que usar funciones (de matemáticas) y una sentencia for. Ahora explicaré en profundidad la sentencia Color.new. Existen ciertas constantes del juego que representan unos colores determinados. Estas constantes son modificables desde la clase Window_Base de los scripts. :: Códigos :: def normal_color return Color.new(255, 255, 255, 255) end def disabled_color return Color.new(255, 255, 255, 128) end def system_color return Color.new(192, 224, 255, 255) end def crisis_color
- 13 return Color.new(255, 255, 64, 255) end def knockout_color return Color.new(255, 64, 0) end Al igual que puedes modificarlos, se pueden añadir más. Sólo hay que poner def (que indica comienzo de un método), el nombre del color; en la línea siguiente la palabra return (que devuelve al código que la llamó la variable que se encuentre detrás suyo) seguida de la Sentencia Color.new que explicamos antes (que contiene un color en RGBA (Rojo, Verde, Azul y Opacidad) siendo la opacidad un parámetro opcional que adopta el valor de 255 si se omite); y en la línea siguiente la palabra end, que indica que el método termina en ese punto. Con esto, un poco de imaginación, y el paint al lado para buscar colores en RGB (Red, Green Blue (Rojo, Verde, Azul)) y para ver donde colocar cada píxel, podéis hacer scripts que dibujen cosas.
7. Condicionales 7.1 If (if then else elsif end) Se corresponde con la sentencia if. Es puesta en azul oscuro, por lo que NO ADMITE MAYÚSCULAS. Corresponde a los condicionales humanos. Su sintaxis es esta: if comparación acciones si se cumple else acciones si no se cumple end else no es siempre necesario, solo se usa en el caso de que queramos usar excepciones. para la comparación necesitaremos conocer los operadores de comparación, que son: == : igual >: mayor que < : menor que >= : mayor o igual que <=: menor o igual que !=: no es igual que Aquí pongo un ejemplo: :: Códigos :: if @imagen !=nil #si la variable imagen no es nula print "no es nula" #muestra un mensaje diciendo que no lo es else #si la variable imagen es nula print "es nula" #muestra un mensaje diciendo que lo es end #finaliza el condicional. De esta manera se comparan dos valores y se hacen cosas distintas según los valores.
- 14 Si se quiere añadir otro condicional cuando la primera condición no se cumpla (cuando se ejecuta el else), se usa la sentencia elseif, que funciona como if, pero sin necesidad del end. :: Códigos :: if @bit = 0 print "no hay señal" elseif @bit = 1 #si bit no es cero, pero es 1 print "hay señal" end Hay otra forma de condicional, mas compleja, pero mas corta, desarrollada en una sola línea. Sirve para dar un valor a una variable, según otros valores. variable = condición ? valor si se cumple : valor si no se cumple Aquí pongo un ejemplo, es usado en las ventanas de objetos, para determinar la opacidad de las imágenes. :: Códigos :: var =algo_a_comparar==un_valor ? “algo es igual a un valor” : “nop” Esto se traduce en que la variable var tendrá el valor de “algo es igual a un valor” cuando la variable algo_a_comparar sea igual a un_valor, y si no lo es tomará el valor de “nop”
7.2 Unless (unless, end) Indica que lo que aparece dentro de dicho condicional solo se ejecutará si la condición puesta no se cumple. Es lo contrario de if, pero no contiene excepciones, ya que lo que ejecuta es la excepción al condicional. Ej: :: Códigos :: unless i = 12 i += 1 end
7.3 Case (case, when, end) Sirve para ejecutar una acción u otra dependiendo del valor de una variable. Sustituye al if cuando hay muchos posibles valores, por lo que ahorra líneas de código. Su estructura es la siguiente case variable_a_comparar when valor_uno acción en caso de que sea el valor uno when valor_dos acción en caso de que sea el valor dos ... end
- 15 Ej: :: Códigos :: case equip_type when 0 # Brazos return $data_actors[@actor_id].weapon_fix when 1 # Escudo return $data_actors[@actor_id].armor1_fix when 2 # Casco return $data_actors[@actor_id].armor2_fix when 3 # Armadura return $data_actors[@actor_id].armor3_fix when 4 # Accesorios return $data_actors[@actor_id].armor4_fix end
8. Bucles 8.1 For (for in end) Este comando azul (NO ADMITE MAYÚSCULAS), es de gran utilidad: sirve para repetir una/s acción/ones un número de veces especificado antes, o sin especificar, es decir que se de por variables. Su estructura es la siguiente: for variable in intervalo operaciones end La variable es una variable que tendrá como valor el punto del intervalo que corresponda. El intervalo puede ser,[dos puntos] primer_número..segundo_número (en intervalos matemáticos sería esto [primer_número, segundo_número] Se incluyen ambos números), o [tres puntos]primer_número...segundo_número ( [primer_número, segundo_número), no se incluye el último número). Otra opción es usar Arrays: :: Códigos :: for i in @array acciones end En tal caso "i" adoptaría el valor de cada uno de los valores de dicho array.
8.2 Next Este comando funciona de la siguiente manera: si se ejecuta dentro de una sentencia for, se produce un salto de nuevo al siguiente valor de la variable establecida.
- 16 EJ: :: Códigos :: # queremos que haga algo 12 veces, pero que no lo #haga a la tercera for i in 0...12 # [0, 12) hay que tener en cuenta que #no coge decimales if i == 3 next #si i es tres, no ejecutará las acciones #siguientes, si no que pasará a i = 4 end operaciones end
8.3 Loop do (Loop do, end) Sirve para repetir algo indefinidamente hasta que se rompa el ciclo con break (luego lo explico). Su estructura es tan simple como: loop do acciones end A pesar de que la palabra loop no esté en azul, se ha de escribir con minúsculas. Desgraciadamente, el loop consume mucho, y es posible que desborde los scripts (el juego se bloquea unos segundos, y luego muestra un mensaje diciendo "Script Desbordado" y tras pulsar aceptar, se cierra).
8.4 Break Como la sentencia loop es infinita, tenemos que poner algo que lo rompa, si no, el juego los códigos se estancarían en una operación que no pararía de repetir. Para romper el ciclo, se necesita la sentencia break, metida, para su control, en un condicional. Ej (esto se usa en las escenas, en su main, para que no se cierre la escena hasta que no se cambie la misma (y para refrescar la pantalla)) :: Códigos :: loop do Graphics.update Input.update update if $scene != self break end end
8.5 While Es una especie de loop do, pero no es infinito. Es decir, el bucle se rompe cuando la condición puesta tras de sí se cumple.
- 17 Vamos a transofrmar el código de antes, en algo más simple con while:
:: Códigos :: loop do Graphics.update Input.update update if $scene != self break end end pasa a :: Códigos :: while $scene == self Graphics.update Input.update update end De todos modos, no lo cambies por lo anterior, que si está así es por algo.
9. Operadores Lógicos: And, Or, Not (and (&&), or (||), not (!)) Imaginemos que en un condicional (o en un While) queremos hacer que funcione sólo si se cumplen dos condiciones. Podemos hacer un condicional, y dentro otro o simplemente usar los métodos and or y not. Estos comandos también pueden ser sustituidos por &&, || y ! respectivamente (no confundir ! (not) con != (distinto de)). En el fondo, el funcionamiento de un condicional es el siguiente. Si tenemos la condición de que cuando x sea igual a un número se ejecuten unas determinadas líneas, entonces el ordenador comprueba la condición. Si x es igual a ese número devolverá un 1 (true) y si no lo es devolverá un 0 (false). Al usar estos operadores lógicos, hacemos al ordenador realizar operaciones lógicas (suma, multiplicación y negación). and: se traduciría del lenguaje RUBY al lenguaje humano como "y”. Es la multiplicación lógica de los resultados (true o false) de dos valores(véase en Variables > Booleanos). Ej: :: Códigos :: if x == 12 and y == 54 ... end También vale esto: :: Códigos :: if x == 12 && y == 54
- 18 ... end He aquí su tabla de la verdad: Tabla de la verdad AND Valor 1
Valor 2
Resultado
false false true true
false true false true
false false false true
or: Se traduce por "o". Corresponde con la suma lógica. Ej: :: Códigos :: if x == 12 or y == 54 ... end También vale esto: :: Códigos :: if x == 12 || y == 54 #el símbolo | se escribe con Alt + Cntrl + 1 ... end He aquí su tabla de la verdad: Tabla de la verdad OR Valor 1
Valor 2
Resultado
false false true true
false true false true
false true true true
not: Se traduce por "pero no". No se corresponde con la negación propiamente dicho, si no por la multiplicación lógica del primer término por la negación (lo contrario) del segundo. Ej: :: Códigos :: if x == 12 not y == 54 ... end También vale esto:
- 19 -
:: Códigos :: if x == 12 ¡ y == 54 ... end He aquí su tabla de la verdad: Tabla de la verdad NOT Valor 1
Valor 2
Resultado
false false true true
false true false true
false false true false
(sólo es válido cuando el resultado de la 1ª condición es verdadero y el de la segunda falso)
10. Números Aleatorios Con Ruby, al igual que con casi todos los lenguajes de programación, se pueden generar números aleatorios. Para ello usamos el comando rand, el cual devuelve un número entre el cero y el uno, y por supuesto con decimales, aunque no es necesario cogerlos. De todas maneras, este comando solo probablemente produzca error, ya que necesita un parámetro, que es un número por el que se multiplicará este valor “aleatorio” situado entre el uno y el cero. Este parámetro se incluye entre paréntesis detrás del comando, de la siguiente manera: rand (número) Es por tanto un comando simple, siempre y cuando se sepa como usarlo. Vamos a usar una pregunta que me hicieron una vez. Imaginemos que queremos obtener un número entre el 100 y el 100 -> número ε [-100, 100] (el numero pertenece al intervalo ...). No existe ningún número que al ser multiplicado por un número entre el cero y el uno nos de o negativo o positivo, por lo que habrá que usar otro método. Bien, intentemos ver cuantos valores de números naturales abarca. La variación de los valores máximos y mínimos de el número es 200 (número mayor menos número menor (100 - (-100) = 100 + 100 = 200)). Ahora tenemos doscientos términos con el código: rand (200), peor ninguno es menor que cero, es en este momento cuando le restamos 100 al número resultado para que nos de un número entre el 100 y el menos 100, resultado que estábamos buscando. :: Códigos :: x = rand (200) - 100
- 20 -
11. Clases (class) 11.1 Introducción La clase es la unidad de ejecución por excelencia. Son bloques de código los cuales pueden ser llamados desde otros bloques u desde el juego, con el comando [llamar script].
11.2 Definición de clases y llamada Para definir una clase como tal, necesitamos dos palabras básicas mas el nombre de la clase: class y end. Vamos a hacer una clase vacía e inútil, sin nada dentro. :: Códigos :: class clase_de_prueba end No tiene ninguna función, no realizará ningún comando, por que no le hemos escrito ningún comando y por que no la hemos llamado. Para llamarla necesitamos una variable vacía el nombre de una clase y el método innato de la clase .new. :: Códigos :: @clase_llamada = clase_de_prueba.new Tras realizar una llamada, lo mejor es comprobar si el nombre de la clase está bien, y si el método .new está escrito con minúsculas. Si se escribe con mayúsculas, no lo entenderá. Si estamos llamando a la clase desde el sistema de acciones del RPG Maker, la variable que contenga la clase tiene que ser global (con el símbolo del dólar $)
11.3 Métodos de clase Si escribimos el código directamente dentro de la clase sin usar métodos, dicho código será ejecutado antes de la carga del juego, y solo entonces. Para evitar que se carguen estos procesos antes de tiempo existen las definiciones. También sirven para controlar que procesos queremos que sucedan. La definición de un Método de clase se realiza con los comandos def y end más el nombre del método. :: Códigos :: class clase_de_prueba def cosas end end Ahora se le pueden añadir comandos a ese método.
- 21 Mas tarde podremos llamar a ese método, bien desde otro método dentro de la misma clase (escribiendo el nombre del método), o bien como método de una variable (un punto mas el nombre del método de clase), usada en otra clase.
11.4 Parámetros en los métodos de clase Un método de clase puede requerir el uso de una variable, la cual necesita ir acompañada de un parámetro para funcionar. Esto se configura en la definición del método, añadiendo el nombre de una variable entre paréntesis. Si queremos emplear ese parámetro después, solo tenemos que poner su nombre, ya que actúa como una variable de método. Se pueden poner todos los parámetros que se quieran. :: Códigos :: class clase_de_prueba def cosas (parametro) end end Si queremos que un parámetro sea opcional, Entonces tenemos que darle a la variable parámetro que está entre paréntesis un valor. El/los parámetro/s que tengan un valor predefinido ha de estar siempre al final. :: Códigos :: class clase_de_prueba def cosas (parametro= ”valor inicial”) end end Hay una pequeña variación de la creación de parámetros que nos permite usar esta definición como si fuera una variable fuera de la clase (dentro sería estúpido). :: Códigos :: class clase_de_prueba def cosas =(parametro) @parametro = parametro #si no ponemos esto el valor #del parámetro se pierde end end Si usáis esto último no se puede poner un valor por defecto. De todas formas, existe una forma más rápida de usar esta, que procedo a explicar en el punto 11.6.
11.5 Superposición de métodos de clase Si escribimos dos métodos de clase con el mismo nombre y el mismo número de parámetros (vale con no poner parámetros), se produce una superposición de métodos, en la cual, el último método leído (el que esté mas abajo en la página de scripts) será el ejecutado. Pero no sucede esto si el número de parámetros es distinto.
- 22 11.6 Formas de acceso a variables de una clase (attr_) Imaginemos que queremos que una variable de una clase sea modificable, o que se pueda leer, o ambas cosas. En tal caso podemos usar métodos de igual nombre pero distinta función: :: Códigos :: #Primer método (lectura) def cosas return @cosas end #Segundo método (escritura) def cosas =(cosas) @cosas = cosas end El primer método permite la lectura de la variable @parámetro, y el segundo su modificación (escritura). Ambos son compatibles si se colocan juntos pero no siempre se quiere crear variables de externa lectura y escritura, quizás solo queramos que se pueda leer o quizás que solo se pueda escribir. Para realizar esto se puede usar el método que queramos, o en el caso de que queramos usar ambas, escribiendo dos métodos similares. Pero existe un sistema mas rápido, las funciones attr. Son tres: attr_reader : cosas ►permite la lectura de la variable cosas desde otras clases que llamen a esta, añadiendo a la variable que contenga la clase donde se coloca esta función un punto y el nombre de la variable, que en este caso es cosas. Ej: algo = @clase1.cosas attr_writer : cosas ►permite la escritura sobre la variable cosas desde otras clases que llamen a esta, de igual modo que el attr anterior. attr_accessor : cosas ►permite la escritura y lectura de la variable cosas desde otras clases que llamen a esta. Es la unión de las dos funciones anteriores. Estas tres funciones se escriben (no escribir las tres con la misma variable no vaya a ser que genere error) debajo de la definición de clase (debajo de la línea donde pone class ...). Otra característica es que generan una variable de clase llamada igual que la variable que se coloca tras los dos puntos (en este caso es cosas), es decir, que produciría con una fórmula attr_... : cosas, una variable llamada @cosas.
11.7 Superposición de clases Si tenemos dos clases del mismo nombre, estas dos se unirán en la memoria del ordenador en una sola clase, en la cual se darán efectos de superposición de métodos. Si dos métodos son iguales, sólo se ejecutará el último.
11.8 Alias Si existe la superposición de clases, y un método de una clase sustituye a otro, cuando queremos que convivan los dos se usa la sentencia alias, la cual se pondría justo antes de la definición del método que sustituye al otro. Alias funciona así: alias :nombre_del_alias :nombre_original_del_método
- 23 En donde pone nombre_del_alias tendríamos que poner un nuevo nick, por así decirlo, al método que es sustituido; y donde pone nombre_original_del_método el nombre original del método, el cual ha de ser distinto del nick (no por que produzca error, si no por que es estúpido). Luego se llamaría a ese método con el nick, dentro del método que no se ha sustituido. Pongamos un ejemplo: :: Códigos :: class opciones def opción_uno (dos) acciones... end end class opciones #aquí va el alias alias :op :opción_uno def opción_uno (suerte) aciones de la segunda ... op(suerte) #fíjense que hay que introducir los argumentos end end
11.9 Subordinación de clases Existe un sistema de unión de clases que no implica superposición de métodos ni de clases, es mas, las clases no tienen por que tener el mismo nombre. Es la subordinación, y se representa en la definición de clase con el símbolo <. Con este sistema se puede usar métodos de la clase que esta superordinada (la que aparece segunda) en la primera. En el caso de que haya dos métodos con igual nombre e iguales parámetros, no se realizará superposición, aunque aparentemente se ejecuta el método de la subordinada (la primera). Existe una forma de llamar al método de la superordinada, que es el comando super(argumentos). Vamos a poner un ejemplo: :: Códigos :: class ejem def dos(arg=nil) p arg end end class Bar < ejem def dos(arg) super(5) #imprime 5 super(arg) #imprime el valor de arg (7) end end Bar.new.dos 7 Este sistema se usa en las clases-ventana (ver punto ??.?), para poder usar en todas los mismos métodos, los cuales se sitúan en la superordinada Window_Base.
- 24 11.10 Clases-Ventana (Windows) Las clases-ventana son unidades básicas visuales de una escena (explicada en el siguiente punto). Cuando abrimos el juego, en el Título, el cuadro que nos permite elegir entre las tres opciones que hay, es una clase ventana, En el menú, el cuadro que nos permite ver a los personajes del grupo, es una ventana. Son pues estas clases unidades de muestra de información. Todas las ventanas que aparecen predefinidas son subordinadas a Window_Base (explicado mas tarde), la cual contiene métodos que son usados en muchas clases-ventanas. Las ventanas son llamadas por las escenas, y en su conjunto las forman. La clase ventana posee unos métodos característicos, el mas importante es initialize, el cual se ejecuta cuando se usa el método .new. En él se añaden argumentos. No se le debe cambiar el nombre a este método. initialize: es el primer método que se ejecuta cuando se llama a la clase-ventana. En él se ponen los argumentos iniciales. Si mantenemos la subordinación a Window_Base, cosa que aconsejo ya que de lo contrario deberíais estudiar su comportamiento, el primer comando que hemos de incluir es la llamada al método de igual nombre de la clase subordinada. Se usa la sentencia conocida super, tras la cual se especifican la posición con respecto al eje X (el margen Izquierdo), la posición con respecto del eje Y (margen superior), el ancho y el alto; separados cada parámetro por comas, en el orden indicado y entre paréntesis. :: Códigos :: super(X, Y, ancho, alto) Tras esto debemos incluir la llamada a contents, lo que nos permitirá escribir sobre la ventana. Como es una propiedad de la clase propia, usaremos self.contents, y luego igualamos esta variable o le damos el valor de un objeto Bitmap (B mayúscula), seguido por el ancho y el alto (los cuales tienen que ser 32 puntos menores que los mismos parámetros de la ventana), separados por comas y entre paréntesis :: Códigos :: self.contents = Bitmap.new(width - 32, height - 32) Las variables de width y height, que parece que me las saqué de la manga, salen de la llamada anterior al método initialize de la superordinada. Tras esto se definen las propiedades .font.name y .font.size de self.contents, y para ello podemos usar tanto los nombres de las fuentes (entre comillas) y su tamaño (número), o bien usar las variables globales $fontface y $fontsize, las cuales se pueden modificar en la página de códigos Main. :: Códigos :: self.contents.font.name = $fontface self.contents.font.size = $fontsize Ahora pongo una lista de comandos con su función para la personalización de la ventana. Son opcionales: self.windowskin : permite cambiar el skin de la ventana. Para dejar el skin normal, omitir. El skin se llama con la sentencia: RPG::Cache.windowskin(skin), donde en skin se pone el nombre del windowskin que queremos usar.
- 25 self.opacity: permite cambiar la opacidad de la ventana, que no es lo mismo que la opacidad del contenido. Para que el skin no se muestre, a esta propiedad se le da el valor de 0 self.z: profundidad. Si queremos que la ventana esté abajo del todo, se le da el valor inferior a 100 y si la queremos sobre el resto de cosas, por encima de 100. Si se omite su valor será 100, y si se ponen dos ventanas superpuestas, la última que fue llamada será la que esté sobre la otra. Por último queda una llamada al método de refresco, que, en el caso de las ventanas, se llama refresh. refresh: en este método se dibujan, por así decirlo, los contenidos de la ventana, ya sean gráficos o textos. Como primera medida, se emplea el comando de self.contents.clear, que limpia la ventana de textos e imágenes, dejándola como una ventana nueva y vacía. Tras esto podemos empezar a dibujar los contenidos de la ventana. Los textos se imprimen con la propiedead .draw_text de self.contents. Esta requiere como parámetros X, Y, ancho, alto, texto, alineación, siendo esta última opcional que toma como valor por defecto 0, que significa alineado a la derecha (1 significa a la izquierda y 2 centrado). Si queremos cambiar el color de un texto, antes de imprimir el texto se escribe la sentencia self.contents.font.color, igualada a un color (explicado en el punto 4.6 Puntos y líneas). Los gráficos a aplicar en las clases ventana fueron explicados en el punto 4.5. update: sólo se usa si el contenido de esa ventana varía con el tiempo, como puede ser un cronómetro. En este método se tiene que hacer una llamada a refresh, y al método update de la clase superordinada (usando super sin ningún argumento).
11.11 Clases-Ventanas de comandos (Selectables) Funcionan casi igual que las ventanas normales, a excepción de que se subordinan a Window_Selectable, que a su vez está subordinada a Window_Base. Son algo mas complejas que las ventanas normales, ya que incluyen la función de elección de opciones. Sus métodos son los mismos que los de las ventanas, pero se añaden algunas cosas: initialize: a todo lo explicado para las ventanas se le une self.index, que indica el índice donde se situará inicialmente el cursor (0 es el primero y si queremos que no se muestre le damos el valor de -1). En el caso de que el número de opciones sea fijo, se le dará el valor a la variable numérica @item_max (no se puede cambiar) del número de opciones. Si no es fijo, se le añadirá en el refresh. Si tiene mas de una columna, se le tendrá que dar el valor numérico de dicha cantidad de columnas a la variable @column_max. refresh: es igual que en las ventanas. Si el número de opciones es variable sugiero usar sentencias for. La opción mas común para dibujar es llamar a un método, que podemos llamar como queramos, aunque, por guardar similitud con los scripts básicos, vamos a llamar draw_item (dibuja_item), la cual tendrá un argumento, que será el index que aplicaremos mas tarde a un array (se supone que para hacer esto se necesitan arrays), el cual fue definido en el refresh (puede estar definido manualmente (@array = [“opción 1”, “opción 2”, “opción 3”, “...”]), o de alguna otra manera (sugiero que miren los scripts predefinidos para ver otras maneras, aunque son todas con las variables de datos $data_). draw_item: esta clase tiene el argumento index, y sirve para dibujar las opciones (si son pocas o simples no merece la pena). Aquí incluyo la fórmula para las x y las y en el caso de que solo haya una columna. :: Códigos :: x = 4 y = index * 32 Aquí incluyo la fórmula para las x y las y en el caso de que haya mas de una columna.
- 26 :: Códigos :: x = 4 + index % @column_max * ((self.width - 64)/@column_max + 32) y = index / @column_max * 32 Si queremos incluir iconos, al la x del icono se la da el valor de la x antes obtenida, y a la x de se le da el valor de x mas un número entre el 26 y el 30 (26 a dos píxeles del icono, 30 a 6 píxeles). update_cursor: solo se usa en el caso de que necesitemos un rectángulo del cursor mas grande o que haga cosas raras. De por si, el rectángulo del cursor tiene 32 de alto, y un ancho especificado en función de las columnas y el ancho de la ventana. :: Códigos :: def update_cursor_rect if @index < 0 self.cursor_rect.empty else #aquí configuramos el cursor self.cursor_rect.set(X, Y, ancho, alto) end end update_help: en el caso de que queramos que use nuestra ventana de comandos una ventana de ayuda, el texto se añadirá en este método con la sentencia: @help_window.set_text, la cual solo requiere un texto entre paréntesis. Para que esto funcione, es necesario en la clase-escena, explicada mas abajo, crear una ventana que contenga la clase Window_Help, y luego usar esa variable a la que le dimos ese valor y aplicarla a la propiedad .help_window de la clase ventana de comandos.
11.12 Clases-Escena (Scenes) La Escena o clase-escena (Scenes) contiene código que reúne otras clases, generalmente ventanas, y las cuales las situa en ella misma. Finalmente, cuando esta clase pasa a ser el valor de la variable global $scene es mostrada en la pantalla del juego, formando así menús, mapas, sistemas de batalla... Estas clases poseen unos métodos característicos. El primero de ellos es el método main el cual ha de ser escrito tal cual, ya que es el principal y el mas importante, a partir de aquí se pueden nombrar el resto de los métodos como se quieran, aunque aconsejo nombres, los cuales, por ser iguales en todas las escenas predefinidas, ayudará el hecho de que los mantengáis. main: es el método principal. Main significa principio, y este nombre se le da al método al cual se acude primero al llamar a la clase escena. En este método se inicia la escena, se configuran los valores iniciales, y se llama a las clases-ventanas. Tras todas las llamadas, se crea el loop, o bucle de recarga, en el cual se llama a el método de recarga de escena, al mismo tiempo que llama al refresco de gráficos (Graphics.update (con mayúscula la G de Graphics)), y el refresco de los imputs o entradas del teclado (Input.update (con mayúscula la I de Input)). En ese mismo loop o bucle se tiene que incluir un sistema de rotura de bucle, por lo que se tiene que incluir dentro del bucle un condicional que se ejecute cuando la variable de escena $scene no sea igual a esa misma clase (se pone self). Por último, justo tras este bucle, se ocultan las clases llamadas con el método .dispose. No se puede añadir argumentos a este método. Olvidaba decir que hay que hacer una llamada al método .transition de Graphics antes del bucle, lo que permitirá que los gráficos se muevan, es decir, que la pantalla no se quede congelada. Después del bucle hay que llamar al método .freeze de Graphics,
- 27 para congelar la imagen y que no se vea como van desapareciendo las ventanas una a una. :: Códigos :: class escena def main # NUNCA PONER ARGUMENTOS #llamada a las clases @clase1 = Clase1.new @clase2 = Clase2.new #Transicción de gráficos (pantalla active) Graphics.transition #loop de refresco loop do Graphics.update #refresco de gráficos Input.update #refresco de teclas update #llamada al método de refresco if $scene != self # condicional para usar break break end end #Parada o congelación de gráficos Graphics.freeze #Destrucción de las clases @clase1.dispose @clase2.dispose end # LO QUE SIGUE SE IRÁ EXPLICANDO Véase que los comandos de destrucción de las clases llamadas solo se ejecutarán una vez que se haya roto el bucle. update (método de refresco): Generalmente se le da el nombre de update, aunque le puedes llamar de otra forma, eso si, no te olvides de cambiar el nombre en el main, cuando se llama a este método en el loop de refresco. En esta clase se llama al método update de las clases-ventana llamadas antes, y en el caso de que haya interacción (generalmente la hay), se usan condicionales con condiciones que llaman a los métodos de Input (con mayúscula la I de Input) .trigger? (pulsación) o .repeat?(mantener pulsado) seguido de paréntesis en cuyo interior se encontraría la Input:: y la tecla correspondiente. Para las teclas aquí les dejo una tabla. Las teclas se pueden modificar pulsando F1 durante la ejecución del juego. Tecla del juego
Tecla del ordenador
Uso
A
Shift, Z
-
B
Esc, Num 0, X
Cancelar / menú
C
C, Espacio, Enter
Aceptar
X
A
-
Y
S
-
Z
D
-
L
Q, Re Pág
Anterior
R
W, Av Pág
Siguiente
Para las teclas de Función (F1, F2... F12) se pone su nombre, es decir, una F y su número. Ej: F9, F6
- 28 :: Códigos :: def update # No recomiendo poner argumentos #actualización de las clases @clase1.update @clase2.update #comprobación de teclas Si se pulsa Enter (C) Hará algo if Input.trigger? (Input::C) acciones ... end #comprobación de teclas Si se pulsa ESC (B) Ira al mapa if Input.trigger? (Input::B) $scene = Scene_Map.new end end # AQUÍ SE PUEDEN AÑADIR MAS COSAS end initialize: este método se ejecuta cuando se usa el método .new de una clase. En este método se añaden los argumentos que no pudiste añadir en el main. Este método se ejecuta antes del main, pero solo si existe. Se suelen poner argumentos opcionales.
12. Clases más importantes 12.1 Window_Base Aquí se explicarán cada uno de los métodos utilizables de Window_Base. text_color(n): devuelve un color en base al número n que pertenece a un número entero del 0 al 7, siendo este el código de colores. 0
1
2
3
4
5
6
7
draw_actor_graphic(actor, x, y): dibuja el gráfico de mapa (character) de el personaje alojado en la variable actor, la cual es una variable objeto que contiene $game_party.actors[ ], estando dentro del paréntesis un número del 0 al 3 entero que corresponderá con el índice del actor. Con la X y la Y, solo decir que la x es respecto a el centro del ancho y la Y con respecto a todo el alto. Según el dibujo que viene acontinuación, es el punto donde señala la flecha:
draw_actor_name(actor, x, y): dibuja el nombre del personaje en color blanco. El argumento de actor es el mismo que en el método anterior, y la X y la Y corresponden al la posición normal. draw_actor_class(actor, x, y): dibuja el nombre de la profesión del personaje seleccionado con actor (mismo sistema de antes) en color blanco. Las coordenadas vuelven a ser normales. draw_actor_level(actor, x, y): dibuja en color azul claro (similar al índice 1 de text_color (n)) la palabra definida en la Base de Datos para nivel, y en blanco el nivel. Los parámetros son iguales que en los anteriores. make_battler_state_text(battler, width, need_normal): DEVUELVE, no dibuja, entre corchetes el nombre del estado del personale correspondiente con la variable battler, que viene a ser exactamente igual que las variables actor anteriores. En width irá el máximo de ancho del texto, y en need_normal, un valor true o false que indicará si se quiere recibir el texto de “[Normal]” cuando el personaje no tenga ningún estado alterado.
- 29 draw_actor_state(actor, x, y, width = 120): Este método dibuja el estado del personaje establecido por actor (mismo tipo que en todas). Las coordenadas son normales, y el ancho es opcional, indica lo mismo que el width del método anterior. draw_actor_exp(actor, x, y): dibuja en color azul claro (similar al índice 1 de text_color (n)) la palabra definida en la Base de Datos para experiencia, y en blanco la experiencia actual, una barra (/) y después la experiencia para el siguiente nivel. Los parámetros son iguales que en los anteriores. draw_actor_hp(actor, x, y, width = 144): dibuja en color azul claro (similar al índice 1 de text_color (n)) la palabra definida en la Base de Datos para vida, y en blanco el nivel de vida actual, una barra y el nivel de vida máximo. Los parámetros son iguales que en los anteriores. draw_actor_sp(actor, x, y, width = 144):exactamente igual que antes, pero en vez de dibujar la vida, dibuja la magia. draw_actor_parameter(actor, x, y, type): dibuja en color azul claro la palabra designada en la BD para el parámetro especificado, y luego en blanco su valor. Los argumentos son los mismos que siempre salvo que incluye el parámetro type, que indicará el parámetro a usar: Clave Parámetro 0 Ataque 1 Defensa física 2 Defensa mágica 3 Fuerza 4 Suerte / Destreza / Crítico 5 Agilidad / Velocidad 6 Poder Mágico / Inteligencia draw_item_name(item, x, y): dibuja un item, con su gráfico. La variable item contiene un objeto $data_items[ ] o $data_weapons[ ] o $data_armors[ ], con su debido número entre los corchetes. Las coordenadas no tienen nada raro.
12.3 Scene’s En este punto intentaré no extenderme mucho, sin explicar algunas clases que, por su falta de calidad, lo mas probable es que sean reemplazadas por otras (me refiero al sistema de batallas). AVISO: nombro a las clases por su nombre real, el nombre de la clase, que generalmente coincide con el nombre de la página donde está dicha clase. En el caso del Sistema de Batallas, solo lo mencionaré una vez, no cada una de las cuatro páginas en las que está dividida la clase Scene_Title: Clase inicial por defecto. Sus primeros comandos son un condicional que indica si es una prueba de batalla o no, para seguir caminos distintos. En el caso de que no lo sea, empezará cargando los datos del juego (almacenados en la carpeta Data). No carga el archivo scripts, ya que ya fue cargado y compilado, es mas, se están ejecutando. Tras esto muestra la imagen de title, y, sobre esta la ventana de opciones (Nuevo juego, Cargar juego y Salir), que no es mas que un Window_Comand, que se explicará en el punto 12.4. Tras esto realiza unas pruebas para indicar si debe estar activa la opción de cargar, y en el caso de que la esté, colocar el cursor sobre ella. Luego carga la música de title, y la reproduce. A partir de allí, sigue igual que todas los métodos main. En el caso de que
12.6 Main (No es una calse) Como primera cosa a decir sobre esta sección, el Main no es una clase, ya que no es definida como tal. Se inicia, a parte de los reminders que aparecen antes, con la sentencia begin, la cual da inicio a la reproducción del juego. Todos los códigos que hayan después de este bloque begin - end no serán ejecutados, y no se considerarán como existentes.
- 30 Tengamos en cuenta que, cuando se le presenta el archivo de códigos al juego en ejecución, este encadena todos los códigos como si sólo fuera una página, y todo lo que haya después de la declaráción antes mencionada, será excluido de la ejecución. Por esta razón no se deben colocar las páginas de scripts por debajo de esta página. La estructura es simple: :: Códigos :: begin $fontface = "Lucinda Console" $fontsize = 30 Graphics.freeze $scene = Scene_Title.new while $scene != nil $scene.main end Graphics.transition(20) rescue Errno::ENOENT filename = $!.message.sub ("No se encontó el archivo o directorio - ", print("Error RGSS: #{filename}") end
#1
#5
#10 "")
La primera línea, se inicia el proceso con la sentencia begin. En la segunda y tercera se definen dos variables de ámbito global llamadas $fontface y $fontsize, que servirán para determinar la fuente que usará el juego la primera, y el tamaño de la fuente, la segunda. Si en una ventana no deseamos que se use los valores definidos por defecto, simplemente tenemos que cambiar la igualación a la variable global antes mencionada por una igualación al valor que queremos. Ej: self.contents.font.name = $fontface >>> self.contents.font.name = “Fuente deseada” En la siguiente línea, la cuarta, se congela la imagen, es decir, que la imagen se quedará en negro, pausada hasta que se reanude el proceso con la sentencia Graphics.update, la cual se tendrá que repetir en un bucle. En la línea quinta, se dirige la escena principal. En este caso inicia con el title. Si quisiéramos que se iniciara con otra escena solo tendríamos que cambiar el nombre de la escena, sin olvidarnos de usar el método .new. :: Notas :: Cuidado si queremos que la primera escena sea un mapa (Scene_map) ya que tendremos que incluir, antes de llamar a la escena, una serie de expresiones que se emplean en Scene title que nos activarán la correcta funcionalidad de la clase. Hay un par de cosas modificables: $data_actors = load_data("Data/Actors.rxdata") $data_classes = load_data("Data/Classes.rxdata") $data_skills = load_data("Data/Skills.rxdata") $data_items = load_data("Data/Items.rxdata") $data_weapons = load_data("Data/Weapons.rxdata") $data_armors = load_data("Data/Armors.rxdata") $data_enemies = load_data("Data/Enemies.rxdata") $data_troops = load_data("Data/Troops.rxdata") $data_states = load_data("Data/States.rxdata") $data_animations = load_data("Data/Animations.rxdata") $data_tilesets = load_data("Data/Tilesets.rxdata") $data_common_events = load_data("Data/CommonEvents.rxdata") $data_system = load_data("Data/System.rxdata") $game_system = Game_System.new Graphics.frame_count = 0 $game_temp = Game_Temp.new $game_system = Game_System.new
- 31 $game_switches = Game_Switches.new $game_variables = Game_Variables.new $game_self_switches = Game_SelfSwitches.new $game_screen = Game_Screen.new $game_actors = Game_Actors.new $game_party = Game_Party.new $game_troop = Game_Troop.new $game_map = Game_Map.new $game_player = Game_Player.new $game_party.setup_starting_members #Aquí va el id del mapa al cual transportar el personaje $game_map.setup(38) #Aquí va la posición inicial sobre el mapa $game_player.moveto(1, 1) $game_player.refresh $game_map.autoplay $game_map.update $active = true $scene = Scene_Map.new En la línea sexta, séptima y octava, se ejecuta un bucle while, con la condición de que si el valor de la variable global $scene, la cual contiene la escena en curso, no es nula, es decir, que hay una escena mostrándose, se ejecutará una llamada al método main de la escena. En el caso de que fuera nula y este método fuese llamado, produciría un error. La línea 9 contiene la llamada a la transición de la escena al negro, que hace que los gráficos se degraden en eso de un segundo (20 frames) antes de que se cierre la aplicación. En las líneas décima, undécima y duodécima se realiza un rescate de código en el caso de que no exista un archivo o carpeta, permitiendo la búsqueda de dicho archivo o carpeta. La última línea está compuesta por un end que, básicamente, cerraría la aplicación. Existe un comando, exit, que nos permitiría cerrar la aplicación en el momento que queramos.