当前位置: 首页 > 工具软件 > multilanguage > 使用案例 >

[重新认识cocos2dx---工具篇] 一 cocos命令行之语言包MultiLanguage

巴英韶
2023-12-01

多语言对于游戏程序的设计来说是很必要的,很意外的是在cocos命令行项目中也发现了这个,就试着分析一下,不喜勿喷。

主体程序是/bin/目录下的MultiLanguage.py和string.json

一 . 用法

#设置语言类型,本例中时'en','zh','zh_tr' 对应英语,简体,台湾
MultiLanguage.set_language('zh')
#获取相应的字符串
MultiLanguage.get_string('COCOS_PARSE_PLUGIN_WARNING_FMT', classname)

二.  分析

首先应该区分在python中的 类方法和 实例方法(详情链接

第一个初始化的方法是不能少的,读取语言的配置信息

    def __init__(self):
        # 获取配置文件的路径
        cfg_file_path = os.path.join(get_current_path(), MultiLanguage.CONFIG_FILE_NAME)

        try:
            # 获取语言和编码方式
            sys_lang, self.encoding = locale.getdefaultlocale()
        except:
            sys_lang = None
            self.encoding = None
            pass

        if self.encoding is None:
            self.encoding = 'utf-8'

        if sys_lang is None:
            cur_lang_key = MultiLanguage.DEFAULT_LANGUAGE
        else:
            cur_lang_key = self.get_lang_key(sys_lang)

        # 读取json文档
        if os.path.isfile(cfg_file_path):
            f = open(cfg_file_path)
            self.cfg_info = json.load(f, encoding='utf-8')
            f.close()

            if self.cfg_info.has_key(cur_lang_key):
                self.cur_lang_strings = self.cfg_info[cur_lang_key]
            else:
                self.cur_lang_strings = None

            if self.cfg_info.has_key(MultiLanguage.DEFAULT_LANGUAGE):
                self.default_lang_strings = self.cfg_info[MultiLanguage.DEFAULT_LANGUAGE]
            else:
                self.default_lang_strings = None
        else:
            self.cfg_info = None
            self.cur_lang_strings = None
            self.default_lang_strings = None
	

	def get_current_path():
		if getattr(sys, 'frozen', None):
			# 获取安装目录
			ret = os.path.realpath(os.path.dirname(sys.executable))
		else:
			# 获取当前文件的目录
			ret = os.path.realpath(os.path.dirname(__file__))

		return ret		
			
		
	def get_lang_key(self, sys_lang):
		# 将系统的语言编号变为自定义的编号 
		sys_lang_info = sys_lang.split('_')
		lang = sys_lang_info[0]
		lang = lang.lower()
		region = None
		if len(sys_lang_info) > 1:
			region = sys_lang_info[1]
			region = region.lower()

		if lang == 'zh':
			if (region is None) or (region == 'cn'):
				ret = lang
			else:
				ret = 'zh_tr'
		else:
			ret = lang

		return ret	


第二个 set_language

@classmethod
def set_language(cls, lang):
	'''
		挺常用的设计思路 单体类,调用实例方法设置当前的语言
	'''
	cls.get_instance().set_current_language(lang)		

@classmethod
def get_instance(cls):
	if cls.instance is None:
		cls.instance = MultiLanguage()

	return cls.instance
	
def set_current_language(self, lang):
	if (self.cfg_info is not None) and (self.cfg_info.has_key(lang)):
		self.cur_lang_strings = self.cfg_info[lang]
	else:
		cocos.Logging.warning(MultiLanguage.get_string('COCOS_WARNING_LANG_NOT_SUPPORT_FMT', lang))
第三个: get_string()

    @classmethod
    def get_string(cls, key, fmt_value=None):
        '''
            获取指定key的字符,或是返回默认值
        '''
        fmt = cls.get_instance().get_current_string(key)

        if fmt_value is None:
            ret = fmt
        else:
         # 拼凑字段 eg: ("%s,%s") %("name","nID") == "name,nID"           
            if isinstance(fmt_value, tuple):
                dst_values = []
                for value in fmt_value:
                    # 转换编码方式
                    if isinstance(value, unicode):
                        dst_values.append(value.encode(cls.get_instance().get_encoding()))
                    else:
                        dst_values.append(value)
                ret = fmt % tuple(dst_values)
            elif isinstance(fmt_value, unicode):
                ret = fmt % fmt_value.encode(cls.get_instance().get_encoding())
            else:
                ret = fmt % fmt_value

        return ret

    def get_current_string(self, key):
        if self.has_key(key, self.cur_lang_strings):
            # 查询到含有所需的字段
            ret = self.cur_lang_strings[key]
        elif self.has_key(key, self.default_lang_strings):
            # 查询到默认表中含有所需的字段
            ret = self.default_lang_strings[key]
        else:
            ret= key
        # 转换编码方式
        if isinstance(ret, unicode):
            ret = ret.encode(self.encoding)

        return ret

    def has_key(self, key, strings_info):
        ret = False
        if strings_info is not None and strings_info.has_key(key):
            ret = True

        return ret

三.  总结

该类的核心方法MultiLanguage.get_string().设计思路也是多语言实现的可行方法之一,值得借鉴。另外类中对编码的转换值得注意

有些方法还是值得借鉴的:

#判读表中是否含有键值key
def has_key(self, key, strings_info):
	ret = False
	if strings_info is not None and strings_info.has_key(key):
		ret = True

	return ret	
	
# 转换编码方式
if isinstance(ret, unicode):
	ret = ret.encode(self.encoding)

# 获取当前文件的目录	
def get_current_path():
    if getattr(sys, 'frozen', None):
        # 获取安装目录
        ret = os.path.realpath(os.path.dirname(sys.executable))
    else:
        # 获取当前文件的目录
        ret = os.path.realpath(os.path.dirname(__file__))

    return ret	
	
# 获取语言和编码方式	
try:
	sys_lang, self.encoding = locale.getdefaultlocale()
except:
	sys_lang = None
	self.encoding = None
	pass


回见
end
 类似资料: