Grimmys / rpg_tactical_fantasy_game

A tactical turn-based game project in pygame, open to support
GNU General Public License v3.0
392 stars 85 forks source link

Multilingual Support #68

Closed JimZhouZZY closed 11 months ago

JimZhouZZY commented 11 months ago

Multilingual Support Description

Introduction

This update adds an interface for implementing multilingual functionality to the game. Due to the unfinished translation work, some content is temporarily missing, but it is harmless, the interface has been completed. I will continue to finish Chinese translation.

How to Add a New Language

  1. Create a language directory: Create a copy of the en folder under the data folder and rename it to the name of the language you need, assuming it is language_name. (Due to the unfinished translation work, some content is temporarily missing.)
  2. Copy font files: Add the font files required for your language in ttf format under the fonts folder.
  3. Import font files: Modify the contents of data/language_name/fonts_description.py and change the name of the font file to the name of the font file you need.
  4. Add language button: Modify the content of the element_grid list in the create_choose_language_menu function in menu_creater_manager.py. Add a button with your language's full name as title and language_name as callback. For example:
    element_grid = [
        [Button(title="English", callback=lambda: buttons_callback("en"))],
        [Button(title="中文简体", callback=lambda: buttons_callback("zh_cn"))],
        ...
        [Button(title="Language Full Name", callback=lambda: buttons_callback("language_name"))],
    ]
  5. The content that needs to be translated includes:
    • Strings, function outputs, and dictionaries in text.py.
    • The content of each txt file under data/language_name/maps/level_number.
    • Some content in each map_properties.tmx file under data/language_name/maps/level_number, including:
      • The value of level_name.
      • The value of main_mission_description.
      • The value of limited_mission_description (if it exists).
    • Some content in some xml files under data/language_name/.
      • The content within the <talk> tag in characters.xml.
      • The content within the <info> tag in alternations.xml.
      • The content within the <info> tag in items.xml.
      • The content within the <info> tag in skills.xml. Please note that the format of the above changes must be: <language_name> translated content </language_name>. For example:
        ...
        <interaction>
        <talk>
            <en> Hurry up ! Leave ... the necropolis. </en>
            <zh_cn> 快呀!从...进入墓地。</zh_cn>
        </talk>
        <talk>
            <en> The clock is ticking... original place. </en>
            <zh_cn> 时钟在滴答...回原来的地方。 </zh_cn>
        </talk>
        </interaction>
        ...

Changes and Explanations

  1. Created src/gui/language.py to handle language-related matters. language.py will import the corresponding text.py according to the language in saves/options.xml.
  2. Moved all static strings involving output in all files to variables in text.py, with variable names composed of uppercase letters and underscores of English content of strings. If the last character of a variable name is an underscore, it means that there is a colon at the end of the string.
  3. Moved all contents involving variables and output in all files to be processed as functions in text.py.
  4. Corresponded all contents involving class names and output in all files with dictionaries in text.py. (The original processing method is temporarily retained for English)
  5. Changed the method of reading <info> or <talk> tags from xml files under the data folder. Added <language_name> tag. (But still retained the original processing method because translation work has not been completed)
  6. Added code related to restarting games in main.py. Used to restart games after adjusting languages. Since I couldn't find a better way to restart games, I used creating subprocesses to implement game restart functionality.
  7. Changed return value type of variable passed to quit_game in each Scene to int. And modified contents of function test_exit_game in test_start_screen.py (modification is very small, just changing True to 1)
    • When quit_game == 2 restart game
    • When quit_game == 1 exit game
    • When quit_game == 0 loop continues
  8. Created src/gui/info_box.py to rewrite InfoBox class. This is because there is a Close button in InfoBox, and I couldn't find a better way to change its text.
  9. Added language-related UI in Option menu.
JimZhouZZY commented 11 months ago

The game after deleting info_box.py requires new release of pygamepopup to run.

Grimmys commented 11 months ago

LGTM, thanks a lot for this big feature 🚀