Cocos2d-x 资源头文件生成脚本
1、简述
近来在学习 Cocos2d-x,在资源管理这一块,因为在代码中使用资源的话,要手动输入文件名,管理起来比较麻烦,也有可能写错。所以写了一个脚本来自动生成资源文件名称 .h 文件,在项目中使用。
比如, 一个普通的 Cocos2d-x 项目的文件夹如下:
我们希望脚本层层遍历 Resources
文件夹下的目录和文件,用目录名做 C++ 的 namespace
名称,用文件名做 C++ 资源变量名。将目录结构按 C++ 代码的方式映射到 Classes/Resources.h
文件中。
- #pragma once
-
- namespace res {
-
- const char* const background = "background.png";
-
- namespace fonts {
- const char* const Consolas = "Consolas.ttf";
- }
- }
2、脚本内容
脚本逻辑也非常简单,用一个递归算法层层遍历文件夹即可,遇到特殊字符的时候,要进行额外处理,确保生成的变量名符合 C++ 的变量名命名规则——这里我将特殊字符替换为了下划线 “_”。具体代码如下:
- #!/usr/bin/env python
- #-*-conding:utf8-*-
- #
- # @author arnozhang
- # @date 2015.11.02
- # @email zyfgood12@163.com
-
- import sys;
- import os;
-
-
- def name_2_var_name(name,full_name = False):
- result = ''
-
- if not full_name:
- pos = name.rfind('.')
- if pos >= 0:
- name = name[0:pos]
-
- if len(name) <= 0:
- return name
-
- for ch in name:
- is_digit = ch >= '0' and ch <= '9'
- is_underline = ch == '_'
- is_upper = ch >= 'A' and ch <= 'Z'
- is_lower = ch >= 'a' and ch <= 'z'
-
- if not (is_digit or is_underline or is_upper or is_lower):
- ch = '_'
- result += ch
-
- first = result[0]
- if first >= '0' and first <= '9':
- result = '_' + result
-
- return result
-
-
-
- def handle_path(file,path,res_path,namespace,indent):
- list = os.listdir(path)
- path_list = []
- for node in list:
- sub_file = path + node
- insert_pos = 0
- if os.path.isdir(sub_file):
- path_list.append(node)
- else:
- path_list.insert(insert_pos,node)
- ++insert_pos
-
- indent_str = ''.join([' ' for i in range(indent * 4)])
- namespace_indent_str = ''
- if indent > 1:
- namespace_indent_str = ''.join([' ' for i in range((indent - 1)* 4)])
-
- file.write('\n\n')
- file.write(namespace_indent_str)
- file.write('namespace ' + namespace + ' {\n\n')
-
- name_list = []
-
- for node in path_list:
- sub_file = path + node
- name = name_2_var_name(node)
- if len(name) == 0:
- continue
-
- if name in name_list:
- name = name_2_var_name(node,full_name = True)
-
- name_list.append(name)
- if os.path.isdir(sub_file):
- sub_res_path = name
- if len(res_path) > 0:
- sub_res_path = res_path + '/' + name
-
- handle_path(file,sub_file + '/',sub_res_path,name,indent + 1)
- else:
- res_file_path = node
- if len(res_path) > 0:
- res_file_path = res_path + '/' + node
-
- generate_res_content(file,res_file_path,indent_str)
-
- file.write(namespace_indent_str)
- file.write('}\n')
-
-
- def generate_res_content(file,indent_str):
- file.write(indent_str)
- file.write('static const char* const ' + name + ' = "' + res_file_path + '";\n')
-
-
- if __name__ == '__main__':
- file = open('./Classes/Resources.h',mode = 'w')
- file.write('#pragma once\n')
-
- handle_path(file,'./Resources/','','res',1)
- file.close()
3、示例
比如,我们有一个项目的 Resources 文件如下组织:
我们运行 python 脚本后,生成的 Classes/Resources.h
文件如下:
- #pragma once
-
-
- namespace res {
-
- const char* const loading = "loading.png";
- const char* const HelloWorld = "HelloWorld.png";
- const char* const CloseSelected = "CloseSelected.png";
- const char* const CloseNormal = "CloseNormal.png";
-
-
- namespace fonts {
-
- const char* const Marker_Felt = "fonts/Marker Felt.ttf";
- const char* const arial = "fonts/arial.ttf";
- }
-
-
- namespace res {
-
- }
- }
以上。