文本本地化#

让我们首先制作一个精简版本的 绘制文本 。我们将在这里对多个文件执行工作,所以我将把所有这些文件放在一个名为 text_loc_example

创建 text_loc_example/text_loc_example.py 使用以下代码:

text_loc_example_start.py#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
"""
Example showing how to draw text to the screen.

If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.text_loc_example_start
"""
import arcade
import os

# Set the working directory (where we expect to find files) to the same
# directory this .py file is in. You can leave this out of your own
# code, but it is needed to easily run the examples using "python -m"
# as mentioned at the top of this program.
file_path = os.path.dirname(os.path.abspath(__file__))
os.chdir(file_path)

SCREEN_WIDTH = 500
SCREEN_HEIGHT = 500
SCREEN_TITLE = "Localizing Text Example"


class MyGame(arcade.Window):
    """
    Main application class.
    """

    def __init__(self, width, height, title):
        super().__init__(width, height, title)

        arcade.set_background_color(arcade.color.WHITE)
        self.text_angle = 0
        self.time_elapsed = 0.0

    def on_update(self, delta_time):
        self.text_angle += 1
        self.time_elapsed += delta_time

    def on_draw(self):
        """
        Render the screen.
        """

        # This command should happen before we start drawing. It will clear
        # the screen to the background color, and erase what we drew last frame.
        self.clear()

        # start_x and start_y make the start point for the text.
        # We draw a dot to make it easy too see
        # the text in relation to its start x and y.
        start_x = 50
        start_y = 450
        arcade.draw_point(start_x, start_y, arcade.color.BLUE, 5)
        arcade.draw_text(
            "Simple line of text in 12 point", start_x, start_y, arcade.color.BLACK, 12
        )


def main():
    MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
    arcade.run()


if __name__ == "__main__":
    main()

这段代码应该可以运行。

未翻译的游戏屏幕

我们将把屏幕上显示的“12磅的简单文本行”翻译成西班牙语。我改编了其中的说明 this blog post 才能做到这一点。

我们将在以下步骤中完成此操作:

  • 从中提取我们要翻译的行 text_loc_example.py 文件放入一个 text_loc_example.pot 文件。

  • 手动翻译这些行。

  • 创建一个可供Python使用的数据库 gettext 此翻译中的模块。

  • 将此翻译加载到游戏中。

从中提取我们要翻译的行 text_loc_example.py 文件。#

首先,将所有面向用户的字符串用 _("my string")

所以在 text_loc_example.py ,我们将面向用户换行:

arcade.draw_text(
    "Simple line of text in 12 point", start_x, start_y, arcade.color.BLACK, 12
)

变成了

arcade.draw_text(
    _("Simple line of text in 12 point"), start_x, start_y, arcade.color.BLACK, 12
)

此时,您的程序将不会运行(因为它正在寻找一个函数 _ 这还没有定义)。这很好,我们会把它修好的。

现在我们需要将这些字符串提取到一个 .pot 文件。为此,我们需要一个外部脚本-- pygettext.py 剧本。

下载 pygettext.py program from the GitHub CPython repo (右击页面,然后选择“页面另存为”选项进行保存。我建议把它留到我们的工作中去 text_loc_example 文件夹以使事情简单)。

从该文件夹中:

python ./pygettext.py -d text_loc_example text_loc_example.py

这将创建 text_loc_example/text_loc_example.pot 。这是一个文本文件,具有我们将能够使用的格式。它看起来是这样的:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2019-05-06 12:19-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"


#: text_loc_example.py:46
msgid "Simple line of text in 12 point"
msgstr ""

将“12磅的简单文本行”行改为 msgstr value below it (I used Google Translate 为了这个)。

msgid "Simple line of text in 12 point"
msgstr "Línea simple de texto en 12 puntos."

将此文件另存为 text_loc_example/text_loc_example.po (我们更改了 .pot 延期至 .po )

让我们进入下一步:

创建一个可供Python使用的数据库 gettext 此翻译中的模块。#

为此,我们需要另一个Python脚本。下载 msgfmt.py script from the GitHub CPython repo (右击页面,然后选择“将页面另存为”选项进行保存)。

我们需要将翻译放入正确的文件夹结构中,这样我们的库才能找到它。创建 my_app.mo folder heirarchy. Because we're translating it into Spanish (whose country codees ),我们必须做出一个 locale/es/LC_MESSAGES 它的目录。

# If you're on Mac/Linux:
mkdir -p ./text_loc_example_locale/es/LC_MESSAGES
# If you're on Windows (TODO: test):
mkdir .\text_loc_example_locale\es\LC_MESSAGES

创建 text_loc_example.mo 文件:

python msgfmt.py -o ./text_loc_example_locale/es/LC_MESSAGES/text_loc_example.mo text_loc_example.po

将此翻译加载到游戏中。#

添加以下代码以加载新的翻译数据库!我已经插入了 ... 就在我放它的地方。

...
import arcade
import gettext
es = gettext.translation('text_loc_example', localedir='text_loc_example_locale', languages=['es'])
es.install()

SCREEN_WIDTH = 500
...

现在,您应该能够使用 es 翻译!

翻译后的游戏屏幕

自动翻译为您用户的语言#

将语言设置为 es 当然,证明我们的翻译是有效的,但大多数情况下,我们希望我们的游戏自动为用户加载正确的语言。为此,请替换行

es = gettext.translation('text_loc_example', localedir='text_loc_example_locale', languages=['es'])
es.install()

使用

gettext.install('text_loc_example', localedir='text_loc_example_locale')

作为 the documentation 表示,此代码在用户的计算机中搜索正在使用的语言,然后 locale 文件夹,以找到要在屏幕上显示的正确语言。

我们可以通过设置 LANG 变量,然后运行程序:

# MacOS / Linux
export LANG=es
python text_loc_example.py
# Windows
set LANG=es
python test_loc_example.py

最终代码#

text_loc_example_done.py#
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
"""
Example showing how to draw text to the screen.

If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.text_loc_example_done
"""
import arcade
import gettext
import os

# Set the working directory (where we expect to find files) to the same
# directory this .py file is in. You can leave this out of your own
# code, but it is needed to easily run the examples using "python -m"
# as mentioned at the top of this program.
file_path = os.path.dirname(os.path.abspath(__file__))
os.chdir(file_path)

# Try to auto-detect the user's language and translate to it
gettext.install('text_loc_example', localedir='text_loc_example_locale')

SCREEN_WIDTH = 500
SCREEN_HEIGHT = 500
SCREEN_TITLE = "Localizing Text Example"
_ = gettext.gettext


class MyGame(arcade.Window):
    """
    Main application class.
    """

    def __init__(self, width, height, title):
        super().__init__(width, height, title)

        arcade.set_background_color(arcade.color.WHITE)
        self.text_angle = 0
        self.time_elapsed = 0.0

    def update(self, delta_time):
        self.text_angle += 1
        self.time_elapsed += delta_time

    def on_draw(self):
        """
        Render the screen.
        """

        # This command should happen before we start drawing. It will clear
        # the screen to the background color, and erase what we drew last frame.
        self.clear()

        # start_x and start_y make the start point for the text.
        # We draw a dot to make it easy too see
        # the text in relation to its start x and y.
        start_x = 50
        start_y = 450
        arcade.draw_point(start_x, start_y, arcade.color.BLUE, 5)
        arcade.draw_text(
            _("Simple line of text in 12 point"), start_x, start_y, arcade.color.BLACK, 12
        )


def main():
    MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
    arcade.run()


if __name__ == "__main__":
    main()

最终目录结构#

text_loc_example/
├── README.md
├── text_loc_example_locale
│   └── es
│       └── LC_MESSAGES
│           └── text_loc_example.mo
├── msgfmt.py
├── pygettext.py
├── text_loc_example.po
├── text_loc_example.pot
└── text_loc_example.py