Jazykové verze v GML: Language Changer
Language Changer – systém zvláště vhodný pro textové hry
Někdy se stane, že člověk potřebuje při tvorbě her nebo jiných plodů Game Makeru větší množství textu přehazovat volně podle jazyka, fáze vývoje a tak podobně. Když jsou texty uvnitř GML kódu je to hrozně nepřehledné a taky to zpomaluje práci. Já jsem vymyslel systém, který s texty zachází snadno a přitom nijak neomezuje při práci. Jednoduše se včlení do jakkoliv složitého kódu a je krásně přehledný. Vlastně se pořád dokola používá jen jedna funkce. Po přečtení článku si stáhněte tento balíček. Je v něm ukázka, kopie potřebných objektů a skriptů. ( objekty se přidávají do GMS jako Add Existing v pravé myši na složku resource )
Jak to funguje?
Pokud chceme, aby s textem šlo volně pracovat, musí být logicky odděleny od kódu souborově. Tzn. ke hře bude přibalen txt soubor s texty, které pak fanoušci – hráči mohou přeložit třeba i do korejštiny. Pokud je třeba úpravám naopak zamezit, je nejsnazší provést kontrolu pomocí md5 a nepovolené úpravy odměnit chybovou hláškou. 🙂
Soubor s texty lze vytvořit i upravovat v jakémkoli editoru, jen musí být zachován prostý textový formát, aby se s textem nenačítaly formátovací značky apod. Text je v souboru rozdělen na klasické počítačové řádky ( řádek je teoreticky nekonečný a je ukončen new líne znakem ). V editoru postačí prostě ukončovat řádek pomocí Enter.
Co je vlastně novinka?
Řádek je u mě rozdělen na dvě části volitelným dělícím znakem. V ukázce jsem používal čárku, ale může to být jakýkoli jinde se nevyskytující znak, např. ¤
Část řádku před dělícím znakem je tzv. přezdívka čili nick. Samotný text je veškerý zbytek řádku za znakem. V GML kódu se pak výhodně použije pouze krátký nick a připravená funkce obstará nahrazení za celý text načtením ze souboru.
Příklad:
Budu chtít mít 4 texty pro hlavní menu. Velký nadpis s názvem hry, položku menu nazvanou Start, další položku Konec a dole bych chtěl malým písmem informaci o copyrightu.
Vytvořím textový soubor „mojetexty.txt“ s tímto obsahem:
BigOne,hra PIMPALIMPIMKINGDOM
Menu1,START
Menu2,KONEC a odchod na párek
kopirak,tento program vytvořil © TomBen v roce 2014
Kód GML:
V GMS do hry natahám objekty a skripty z balíčku. Vytvořím prázdný objekt bez sprite a jako parent mu nastavím přibalený objekt c_lang. Prázdnému objektu přidám UserEvent15 ( právě tento to musí být ) a do této události vložím nastavení:
filename=’mojetexty.txt‘; // název souboru
divider=‘,‘; //dělící znak
display_items=0; // ladicí funkce nemá vypsat žádné pomocné texty
show_catalog_size=false; //ladicí funkce nemá ukazovat počet textů
Tím je připravený objekt s jazykovou verzí. Objekt obsahuje katalog textů a může být v místnosti právě jen jeden. Připraveno jich ovšem můžeme mít nespočet. Když chceme změnit verzi, použijeme prostě instance_change, jak je vidět i v LanguageChangerSample z balíčku.
Aby se načetl obsah souboru, je třeba použít funkci lang_init(). V ten okamžik už musí být v místnosti výše zmíněný objekt s jazykovou verzí. Funkci lze volat z jakéhokoli kódu, kteréhokoli objektu. Načtení ze souboru je třeba zopakovat, pokud změníme jazykovou verzi nebo pokud bychom měnili obsah textového souboru během hry. Jinak se totiž texty berou z paměti a změnu by bez lang_init() nebylo vidět. Pokud lang_init() nepoužijeme vůbec, bude katalog textů prázdný a bude místo textů dávat všude -1.
Použití v kódu je pak už to nejsnazší. Kdekoli dáme draw_text a v něm můžeme místo textu napsat lang(nick) a je hotovo. Tzn. v mém příkladu se souborem moje_texty.txt bych to měl nějak takto.
//tady by se mělo nastavit pěkně velký font
draw_text(10,10,lang(‚BigOne‘); //velký nadpis
//tady by se mělo nastavit font pro menu
draw_text(room_width/2,100,lang(‚Menu1‘)); //menu start
draw_text(room_width/2,150,lang(‚Menu2‘)); //menu konec
//tady by se mělo nastavit malý font pro copyright
draw_text(10,room_height-20,lang(‚kopirak‘)); //© dole
Technické programátorské pozadí čili kodérova prdel
Technicky vzato funkce lang(nick) vrací textový řetězec z druhé části řádky textového souboru, kde se nachází shodný nick. Nicky se nesmí opakovat, ale mohou být stejné jako názvy objektů nebo proměnných.
Katalog textů je řešen uvnitř třídy c_lang jako asociativní pole, v současnosti v YYG celkem oblíbená struktura ds_map. Třída obsahuje v Eventu12 metodu vytvářející cvičný textový soubor. Takže pokud bojujete s umisťováním souborů ( jako já 🙂 ) můžete si při ladění nechat soubor vytvořit přímo za běhu. V ukázce z balíčku je ještě pěkná a všeobecně použitelná třída c_button, která udělá z každého objektu klikací tlačítko. Pokud bude zájem o vysvětlení, můžete mi napsat PMko.
Kdy použít a kdy ne?
Možná to vypadá složitě, ale v přiloženém balíčku je ukázka s textem ve dvou jazykových verzích a je to myslím jednoduché a téměř pro Copy – Paste použití.
Určitě nemá smysl to používat když půjde o dva nápisy navíc předem známé, ale pokud by byla hra vysloveně založená na textu, trocha času věnovaná do vyzkoušení se mnohonásobně vrátí. Systém jsem vyzkoušel pod Windows 7 jako exe i install, v HTML5 exportu to fungovalo taky. Ladicí funkce používejte jen pod Windows. Je celkově výhodné u finální hry všechny textové soubory naházet do Included Files, aby byly do hry zabaleny. Pak se nemusí řešit cesty a přístupová práva k souborům, protože se to vysype vždycky do správné dočasné složky na všech platformách.
8 odezev
Hele, vypadá to parádně… Zrovna dělám na jednom projektu, kde bude angličtina/čeština takže by se mi snadný způsob na vložení textů hodil. Externí txt soubor je ideální věc. Tvořit vlastní systém se mi moc nechce – kdysi jsem tohle řešil přes globální proměnné, ale to je na prd. 🙂
Jen v ukázce nikde nevidím txt soubor s textem. Odkud to tedy data načítá?
Jak jsi na tom s použitím v projektech ostatních? Nebráníš se tomu?
V ukázce je textový dokument zabalený v exe a při spuštění se vysype do tempu. Je vidět v projektu, v included files. Pak se dá teoreticky odchytit za běhu. Jsou tam dva soubory: language.cz a language.en. V projektu je pak ještě jeden testovací file. Moc textu v nich není, jsou jenom pro tu ukázku, takže dva řádky v každém a testovací file má tři řádky. 😀
Pokud se ptáš, jestli můžeš systém použít ve svých programech, tak odpověď je ANO. Proto jsem to zveřejnil – aby se to používalo. Když mě občas někdo zmíní v credits, budu rád, ale netrvám na tom. Asi bych byl nerad, kdyby to někdo prodával za peníze nebo třeba vydával za čistě svůj vynález. Tolik asi pravidla použití.
Asi jsi právě vyřešil problém s jazykovými verzemi v Cubesis. 😀 Doufám, že „prodávání za peníze“ se týká zde uvedených věcí, nikoliv použití v komerčních hrách. V credits tě samozřejmě uvedu. 🙂
To je geniální. Mám radost. 🙂 Úplně mi spadl kámen ze srdce. To asi Cubesis bude vážně i ve španělštině. 😀
To jsem rád, že jsem pomohl. 🙂
Určitě to můžeš použít i ve hře s komerčním záměrem.
Napadá tě, proč mi to nezobrazuje české znaky? Před výpisem určitě nastavuji font, který je podporuje (a bez jazykového systému to běží dobře).
draw_set_font(font0);
draw_text_color(view_xview[0]+vychozi_x, view_yview[0]+vychozi_y,lang(„tip1a“),c,c,c,c,.6)
Asi bude problém s texťákem. Z ukázkového souboru mi to běží, ale z vlastního ne. Myslel jsem si, že byl problém s tím, že jsem neměl zakliknuto „Style: Central Europe“, ale nic se nezměnilo. Takže jsem to prostě musel hodit do toho tvého původního, abych tam měl háčky a čárky. Vážně divné.
Nejspíše kódování samotného texťáku. V obyčejném notepadu to změnit asi nejde, ale například v PSPadu ano.
S největší pravděpodobností je to jak píše Firejs. Prostě je třeba to uložit v něčem, co umí nastavit kódování. Ve Win7 to umí i ten notepad. Funkce lang() sama nijak nerozhoduje o obsahu a bere to, co načte. I když jsem to nezkoušel, tak by to určitě četlo i neviditelné znaky.