Como cambiar el idioma de tu juego
Vamos a aprender como controlar y cambiar el idioma de tu juego. Si te interesa hacer juegos en múltiples idiomas, es posible gestionarlos dentro del mismo juego, detectando el idioma del usuario y darle la opción de poder cambiarlo en cualquier momento.
Como detectar el idioma de tu dispositivo
Game Maker Studio tiene una función que nos permite detectar qué idioma tiene el ordenador, móvil, tablet o incluso el navegador, dependiendo de la exportación que tengamos de nuestro proyecto. La función es os_get_language()
. Nos devuelve uno de estos 15 idiomas (tal y como aparece en la ayuda oficial)
Idioma | Código |
---|---|
Árabe | ar |
Chino | zh |
Danés | da |
Inglés | en |
Francés | fr |
Alemán | de |
Griego | el |
Italiano | it |
Japonés | ja |
Noreguo | no |
Polaco | pl |
Portugués | pt |
Ruso | ru |
Español | es |
Sueco | sv |
Imagina que nos devuelve el castellano, con su código “es”. Sabemos que el castellano puede hablarse en diferentes partes del mundo, y es posible que nos interese lo que en juegos se llama localización: expresiones diferentes, palabras concretas en algún momento, etc. Para poder localizar tu juego, tenemos la función os_get_region()
. El valor devuelto lo podemos consultar en este artículo de la Wikipedia.
De esta manera, podemos detectar el idioma y asignarle que ese sea su valor por defecto. Además, podemos concretar el país, si queremos tener diferentes idiomas con localización.
Yo para almacenar el idioma lo guardo en una variable global, para poder usarla en cualquier objeto. Ponemos esta línea en el primer objeto que ejecutará nuestro juego (yo suelo crear un objeto solo para configuraciones).
global.language = os_get_language();
Ahora vamos a ofrecer distintos idiomas.
En el menú principal de un juego, suelo crear una opción para poder cambiar los idiomas.
¿Por qué?
En mi caso, dónde vivo se habla catalán, y dentro de las opciones de Game Maker no puedo detectar ese idioma. También te puedes encontrar que tengamos a un inglés o alemán viviendo en tu país, y se siente más cómodo jugando con su idioma nativo. Ofrecer al usuario cambiar el idioma le da un valor añadido a tu juego.
Creo una room sencilla con diferentes botones para poder cambiar el idioma. Si tenemos un objeto de castellano y otro de inglés, cuando hacemos click en él, solo tenemos que cambiar el valor de la variable global.
Por ejemplo, en inglés
global.language = "en";
en castellano
global.language = "es";
y en catalán me invento el código
global.language = "ca";
y de esta manera cambiamos el idioma del juego. Así, cuando salgamos de la room ya tenemos el idioma cambiado.
Como gestionamos los diferentes textos con los idiomas
Ahora vamos a gestionar todos los textos que aparecen en nuestro juego. Podemos hacerlo de muchas maneras, así que os ofrezco dos: una si tienes pocos textos, para tenerlos dentro del mismo código, y otra gestionando ficheros, ideal si tienes muchos textos (como en una aventura gráfica o un juego de rol).
Para gestionar los idiomas le daremos un código identificativo a cada texto. Por ejemplo, el código menu_settings será el que devuelva el texto SETTINGS en inglés u OPCIONES en castellano.
Gestionar idiomas dentro del código
Creamos un script nuevo (se puede hacer desde Resources – Create Script). Yo lo llamaré read_text()
.
Tendrá un argumento o parámetro, dónde le pasaremos el código que hemos comentado antes. Un fragmento del código del script:
///read_text(code_text) code_string = argument0; text_string = ""; switch (code_string) { case "menu_settings": { switch (global.language) { case "es": {text_string = "OPCIONES"; break;} case "ca": {text_string = "OPCIONS"; break;} case "it": {text_string = "OPZIONI"; break;} default: {text_string = "SETTINGS"; break;} } break; } } return text_string;
En este caso, tenemos castellano, catalán, italiano e inglés. Hemos puesto el inglés como idioma por defecto, es decir, si no tenemos el texto en el idioma elegido, que por defecto se vea en inglés (podéis poner castellano por defecto si queréis).
¿Porqué digo que esto funcionaría con pocos textos? Por cada nuevo texto deberías de añadir un nuevo switch (global.language) {...}
, y gestionarlo puede ser un poco caótico. Además, añadir un nuevo idioma implica un nuevo case ""
:, así que tocar el código puede ser un poco farragoso.
Como llamaríamos al script de idioma
Ahora creamos un objeto nuevo llamado obj_score, que mostrará un texto con la puntuación que llevamos. Antes de nada, debemos de añadir el nuevo texto en el script read_text()
case "score": { switch (global.language) { case "es": {text_string = "PUNTOS: "; break;} case "ca": {text_string = "PUNTS: "; break;} case "it": {text_string = "PUNTI: "; break;} default: {text_string = "SCORE: "; break;} } break; }
En el evento Create del objeto nuevo, creamos la variable text_score, y le damos valor con el script, pasándole por parámetro el código de texto.
También se podría escribir con GML
text_score = read_text("score");
Y ahora solo hay que llamar al evento Draw, escribiendo el siguiente código
///Draw score draw_text(x, y, text_score + string(score));
¿Porqué no hemos escrito esto?
///Draw score draw_text(x, y, read_language("score") + string(score));
Funcionaría igual, pero es mejor llamar al script una sola vez, que llamar cada vez en el evento Draw. ¡Y más si usamos ficheros para los idiomas!
Gestionar idiomas con ficheros
Ya hablamos en su momento como funcionan los ficheros ini, que tienen una estructura particular para guardar configuraciones. Vamos a aprovecharnos de esa estructura para los idiomas. Crearemos un único fichero llamado language.conf, la extensión da un poco igual, y tendrá la siguiente estructura por dentro:
[es] menu_settings="OPCIONES" score="PUNTOS: " [ca] menu_settings="OPCIONS" score="PUNTS: " [it] menu_settings="OPZIONI" score="PUNTI: " [en] menu_settings="SETTINGS" score="SCORE: "
La sección tendrá el código del idioma, la clave tendrá el código de texto y el valor será diferente, dependiendo de dónde nos situamos cada vez.
El script nuevo, al que llamaremos read_text_ini()
, tendrá el siguiente código
///read_text_ini(code_text) code_string = argument0; text_string = ""; ini_open("language.conf"); text_string = ini_read_string(global.language, code_string, "") //Language Default if (text_string = "") { text_string = ini_read_string("en", code_string, "") } ini_close(); return text_string;
Supongo que el código es suficientemente claro: abrimos el fichero, leemos su valor, hacemos una pequeña comprobación por si queremos un idioma por defecto, cerramos fichero y devolvemos con return
el texto.
El objeto que muestra el valor, funcionará exactamente igual, la única diferencia es que llama a otro script.
Y sobretodo, ¡NUNCA! llaméis al script desde un evento Step o un evento Draw. Os iría tan lento que sería injugable. Por eso leemos el texto en el evento Create, y tenemos el texto llamándolo solo una vez por objeto.
De esta manera, si queremos añadir un idioma nuevo, solo hay que copiar una sección, renombrarla y cambiar los valores de cada texto. Además, añadir un idioma nuevo no supondría una nueva actualización de tu juego, ya que solo es necesario sustituit el fichero.
Conclusión final
Espero que os haya gustado este pequeño ejemplo de como gestionar y cambiar el idioma de tu juego. También se podría gestionar con sprites, detectando la imagen que nos interesa dependiendo del idioma elegido.
Tenéis un pequeño proyecto que he hecho de ejemplo, dónde se puede ver las dos opciones que he comentado de script, más un menú por si quieres cambiarlo.
Espero que os sirva como siempre. Si tenéis alguna sugerencia, ya sabéis, podéis hacerlo en el formulario de Contacto o en los comentarios.
¡Nos vemos!
Buena explicacion, intentare implementarlo en mi juego.
excelente pagina !!!
Me alegro un montón que te sirva. Nos vemos por aquí.
hola como esta me gusto mucho tu guía, podrías dar una guía de como podemos guarda un objeto dentro de otro objeto y que salga al asar de manera aleatoria como si fuera una baraja de cartas es que quiero hacer un juego de carta al estilo yugioh y magic. podrias hacerlo te lo agrade seria mucho
Hola jeibin777,
para guardar objetos dentro de otro, simplemente utiliza una variable y le asignas el objeto. Por ejemplo:
a = obj_carta;
Si quieres aleatoriedad, puedes usar la función
choose()
, hasta 15. Ejemplo:a = choose(obj_carta1, obj_carta2, obj_carta3);
Si quieres más, puedes usar una lista y desordenarla con
ds_suffle()
.En que versión de game maker pudiste cambiar el idioma de el juego
Con lo que he explicado, deberías de poder en cualquier versión, ya que en todas puede leer inis.
Hola,
Enhorabuena por tu aportación y gracias.
He leido este manual tuyo y me parece correcto tal y como lo abordas y explicas. Presentando las distintas opciones aunque no se toca el tema de idiomas tales como Arabe, Ruso, Hindú o chino que tiene otro tipo de caracteres. Podrias contarme como se haria esto.
Sé que existe la manera de añadir una fuente por ejemplo HINDU.ttf en include files y luego crear una fuente en codigo con font_create además de tener tu archivo .ini con la correcta codificación de hindu. En mi caso tengo todo esto hecho y cuando va a leer el del fichero siempre me trae una cadena vacia.
Agradeceria cualquier orientación que pudieras darme.
Gracias
¡Hola Yoorch!
Cuando añades una fuente como recurso en tu proyecto, Game Maker te genera la fuente como imágenes (lo mete dentro de las páginas de textura) y por eso no aparece el texto.
Navegando por el foro oficial de YoYogames, he visto una posible solución:
https://forum.yoyogames.com/index.php?threads/using-japanese-characters-in-game-maker.3984/
Añades la fuente, el fichero HINDU.ttf, como un fichero externo, en Included Files, y luego creas la fuente con la función
font_add()
. Yo lo añadiría en una variable global, rollo así,global.font_hindu = font_add( 'Hindu', 24, true, true, 0, 65536);
Y luego usas el texto con esa fuente, ya que las letras las genera dinámicamente.
Recuerda que el fichero .ini tiene que estar en fotmato UTF-8, para que coja los caracteres bien, y el rango de la fuente tiene que ser para que coja todo el Unicode.
Si puedo hacer un ejemplo lo añadiré en el post, pero basicamente es lo que te he comentado.
Hola! Estoy traduciendo mi juego a chino, japones, ruso…y justamente me he topado con este problema. Creo que he entendido como solucionarlo gracias a tu comentario, pero lo único que no sé como hacer es crear el archivo ini en formato UTF-8. ¿Como se tendría que hacer?
Te paso enlace de ayuda de Game Maker dónde lo comenta:
https://docs.yoyogames.com/source/dadiospice/002_reference/file%20handling/ini%20files/index.html
Es decir, debes crear el fichero ini antes en UTF-8, y luego añadirlo. De esta manera, las funciones de lectura del ini desde GMS funcionaría (entiendo que no vas a escribir?
¿Y como crearlo? Puedes usar algún editor de textos avanzado, por ejemplo en Notepad++ puedes elegir en el menú “Lenguaje – Ini File”, que solo te sirve para ayudarte a la hora de escribir, y también en el menú “Codificación – Codificar en UTF-8”. Así puedes crear el fichero como te interesa.
En donde tengo que poner los codigos para que al presionar un boton, el juego cambie de ingles a frances, por ejemplo.
Hola Rodrigo,
creo que en el proyecto de ejemplo se ve. En los botones para cambiar de idioma, es suficiente cambiar la variable
global.language
. Por ejemplo, en el botón de inglésglobal.language = "en";
y en el botón de francés
global.language = "fr";
Al ser una variable global ya funcionaría en todos los objetos, ya que el script
read_text()
la usa.Lo único que quizás tengas que tener en cuenta es que si esos botones tienen textos traducidos, tendrás que actualizarlos todos al pulsar el botón.
esta bueno lo que explican. pero para alguien que no sabe mucho de esto, donde tengo que poner esos codigos para cambiar el idioma del juego? es eso lo que no entiendo
Tienes un proyecto de ejemplo al final.
Hola David, muy bueno el artículo pero lamentablemente no resuelve el problema que estoy teniendo, si quisiera agregar algún idioma donde los caracteres no son nuestro abecedario, Ruso por ejemplo o Hindi, ¿se puede hacer?
Se puede hacer, pero no puedes añadir la fuente como recurso. Buscaré como hacerlo y pongo un ejemplo.