![]() |
|
How to display chinese In allegro5? |
Quanwei Yuan
Member #14,752
December 2012
![]() |
Hi, I'm come from Zhengzhou City Henan Province China.I have one big problem about how to display the Chinese in allegro program. I have read the allegro manual . It is said that allegro is supported the TTF and UTF-8. I think use the TTF can display chinese, however it is can't display any chinese words? Who can help me? I am sorry my English is so poor, I hope you can understand my problem! below is my code and I use the VC10(VS2010).thx everyone! 1
2//头文件
3#define ALLEGRO_NO_MAGIC_MAIN
4#include <Windows.h>
5#include <allegro5/allegro.h>
6#include <allegro5/allegro_font.h>
7#include <allegro5/allegro_ttf.h>
8#pragma comment(lib,"allegro-5.0.7-mt-debug.lib") //链接Allegro的库
9#pragma comment(lib,"allegro_font-5.0.7-mt-debug.lib") //链接Allegro的库
10#pragma comment(lib,"allegro_ttf-5.0.7-mt-debug.lib") //链接Allegro的库
11////////////////////////////////////////////////////////////////////////////////////////////
12
13//函数
14int game_init(); //初始化游戏
15int game_run(); //进入游戏循环
16int game_frame(); //逻辑处理函数
17int game_render(); //渲染函数
18int game_distory(); //释放资源
19int game_msg(); //消息处理
20
21//常量
22const int WIN_WIDTH =800; //窗口宽度
23const int WIN_HEIGHT =600; //窗口高度
24//全局变量
25ALLEGRO_DISPLAY *display; //显示设备
26ALLEGRO_EVENT_QUEUE *queue; //事件队列
27ALLEGRO_EVENT my_event; //事件
28ALLEGRO_FONT *font=0;
29ALLEGRO_USTR *ustr;
30
31////////////////////////////////////////////////////////////////////////////////////////////
32int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd )
33{
34 int error=0;
35
36 //把游戏初始化的代码写在我们的 game_init()函数里
37 //然后放到这里执行
38 //把game_init()的返回值赋给error
39 //error如果为0的话表示一切正常,初始化成功了!
40 //如果不为0的话,表示初始化的时候,发生了意外。
41 //需要立即结束程序,并返回错误码
42 error=game_init();
43 if(error!=0)return error;
44
45
46 //初始化完成后,开始进入游戏的主循环,
47 //在主循环里将循环执行,消息处理,逻辑处理,和渲染函数
48 error=game_run();
49 if(error!=0)return error;
50
51
52 //游戏结束后,销毁所占用的资源
53 error=game_distory();
54 if(error!=0)return error;
55
56 return 0;
57}
58
59int game_init(){
60
61 if (!al_init())return 1;
62 /************************************************************************/
63 /* 使用al_init()来初始化Allegro系统
64 al_init实际上是一个宏,他实际上调用了
65 al_install_system(ALLEGRO_VERSION_INT,atexit)
66 该函数的返回值是布尔型,初始化成功则返回true,否则返回false */
67 /************************************************************************/
68
69 al_init_font_addon();
70 al_init_ttf_addon();
71 al_install_mouse();
72 al_install_keyboard();
73 /************************************************************************/
74 /* 初始化鼠标,和键盘设备,以便Allegro可以接收到鼠标和键盘消息 */
75 /************************************************************************/
76
77 //al_set_new_display_flags(ALLEGRO_FULLSCREEN);//如果取消掉本行注释就是全屏模式
78 display = al_create_display(WIN_WIDTH, WIN_HEIGHT);
79 if (!display)return 2;
80 /************************************************************************/
81 /*ALLEGRO_DISPALY *al_create_display(int w,int h) 创建显示设备
82 参数 w 为要创建的窗口的宽度
83 参悟 h 为窗口的高度
84 成功则返回一个disply的指针,否则返回NULL
85 /************************************************************************/
86 //设置Windows的标题
87 al_set_window_title(display, "Allrgro系列教程(四) 显示文字");
88
89 //初始化事件队列,接受到的消息将存储在该队列里
90 queue = al_create_event_queue();
91 //指定要接收哪个设备的消息
92 al_register_event_source(queue, al_get_keyboard_event_source());
93 al_register_event_source(queue, al_get_display_event_source(display));
94
95 font=al_load_ttf_font("C:/Windows/Fonts/SIMYOU.TTF",24,0);
96 if(!font)return 3;
97 ustr =al_ustr_new("你好!");
98 if(!ustr)return 4;
99
100 return 0;
101}
102int game_msg(){
103
104 al_wait_for_event(queue,&my_event);
105 /************************************************************************/
106 /* 函数原型
107 void al_wait_for_event(ALLEGRO_EVENT_QUEUE *queue,ALLEGRO_EVENT *ret_event)
108 等到队列里有新事件时,将新事件的内容复制到 ret_event里,并从事件队列里移除它
109 */
110 /************************************************************************/
111 if(my_event.type==ALLEGRO_EVENT_DISPLAY_CLOSE)return 98; //当窗口被关闭时
112 if (my_event.type == ALLEGRO_EVENT_KEY_CHAR) {
113 if (my_event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)//当按下 ESC键时
114 return 99;
115 }
116 return 0;
117
118}
119
120int game_frame(){
121 return 0;
122}
123
124
125
126int game_render(){
127 //用指定的颜色填充屏幕
128 al_clear_to_color(al_map_rgb(0,0,0));
129 //al_draw_text(font,al_map_rgb(255,0,0),0,0,0,"你好");
130 al_draw_ustr(font,al_map_rgb(255,0,0),0,0,0,ustr);
131 //翻转
132 al_flip_display();
133 return 0;
134}
135
136
137
138int game_run(){
139
140 //下面的变量用来记录时间,单位是秒
141 //用以控制帧率(FPS),也就是每秒画面刷新多少帧,
142 //这里我们设FPS为30,用 1秒的时间单位/FPS
143 //也就是0.033,也就是说,每次刷新的间隔时间不能小于0.033秒
144 double t_now=0.0; //当前时刻
145 double t_pre=0.0;
146 int error=0;
147 while (true)
148 {
149 if(!al_is_event_queue_empty(queue)){ //先检测事件对了中是否有新事件
150
151 error =game_msg(); //有 则先处理事件
152 if(error!=0)return error;
153 }else{
154 //如果 事件队列中没有新事件 则
155 //计算事件间隔时候大于0.033
156 t_now=al_get_time();
157 if(t_now-t_pre>=0.033){
158
159 //如果时间间隔合适的话就
160 //更新一帧的游戏逻辑
161 error=game_frame();
162 if(error!=0)return error;
163 //刷新画面
164 error=game_render();
165 if(error!=0)return error;
166 t_pre=t_now;
167 }else{
168 //当CPU可以处理游戏逻辑的能力超过我们的需要时
169 //调用Sleep(0)
170 //这个Windows API 将使当前的线程释放出自己的控制权,
171 //这一点对Windows平台很重要,可以使游戏不至于占用全部
172 //的CPU,每次切换游戏的进程,都把可以用的时间片用完了
173 Sleep(0);
174 }
175 }
176
177 }
178 return 0;
179}
180
181
182int game_distory(){
183 al_destroy_font(font);
184 return 0;
185}
|
Matthew Leverton
Supreme Loser
January 1999
![]() |
|
Thomas Fjellstrom
Member #476
June 2000
![]() |
Please put your code in <code></code> tags. That said, make sure your files are saved in UTF-8, not any ASCII code page or other versions of unicode. (and what Matthew just said...) One other thing, you can use al_rest instead of Sleep. -- |
Quanwei Yuan
Member #14,752
December 2012
![]() |
Make sure your font supports those characters ______ I have to convert that source file to UTF8,but still can not display Chinese characters. What other ways can dispaly Chinese character? |
Thomas Fjellstrom
Member #476
June 2000
![]() |
If it still isn't showing up, make sure the font you loaded has the exact characters you're trying to show. -- |
Elias
Member #358
May 2000
|
In Visual Studio, go to File -> Advanced Save Options. Make sure the encoding is set to UTF8. -- |
AMCerasoli
Member #11,955
May 2010
![]() |
It's suspiciously incredible how accurate the Google translator is when translating that file. It's like you have translated from English to Chinese.
|
Elias
Member #358
May 2000
|
I think it's more that Google's translation looks at the context. Then when it knows the text is about programming, it uses a matching dictionary. -- |
beoran
Member #12,636
March 2011
|
The following code works fine for me on Linux. gcc forum_2.c -I /usr/local/include -L /usr/local/lib -lallegro_color -lallegro_font -lallegro_ttf -lallegro -o forum2
I have to put the font in the same place as the forum2 executable. What do you see? Please check if you are using utf-8, and if your font file is OK. 1//头文件
2#include <allegro5/allegro.h>
3#include <allegro5/allegro_font.h>
4#include <allegro5/allegro_ttf.h>
5////////////////////////////////////////////////////////////////////////////////////////////
6
7//函数
8int game_init(); //初始化游戏
9int game_run(); //进入游戏循环
10int game_frame(); //逻辑处理函数
11int game_render(); //渲染函数
12int game_distory(); //释放资源
13int game_msg(); //消息处理
14
15//常量
16const int WIN_WIDTH =800; //窗口宽度
17const int WIN_HEIGHT =600; //窗口高度
18//全局变量
19ALLEGRO_DISPLAY *display; //显示设备
20ALLEGRO_EVENT_QUEUE *queue; //事件队列
21ALLEGRO_EVENT my_event; //事件
22ALLEGRO_FONT *font=0;
23ALLEGRO_USTR *ustr;
24
25////////////////////////////////////////////////////////////////////////////////////////////
26int main(void) {
27 int error=0;
28
29 //把游戏初始化的代码写在我们的 game_init()函数里
30 //然后放到这里执行
31 //把game_init()的返回值赋给error
32 //error如果为0的话表示一切正常,初始化成功了!
33 //如果不为0的话,表示初始化的时候,发生了意外。
34 //需要立即结束程序,并返回错误码
35 error=game_init();
36 if(error!=0)return error;
37
38
39 //初始化完成后,开始进入游戏的主循环,
40 //在主循环里将循环执行,消息处理,逻辑处理,和渲染函数
41 error=game_run();
42 if(error!=0)return error;
43
44
45 //游戏结束后,销毁所占用的资源
46 error=game_distory();
47 if(error!=0)return error;
48
49 return 0;
50}
51
52int game_init(){
53
54 if (!al_init())return 1;
55 /************************************************************************/
56 /* 使用al_init()来初始化Allegro系统
57 al_init实际上是一个宏,他实际上调用了
58 al_install_system(ALLEGRO_VERSION_INT,atexit)
59 该函数的返回值是布尔型,初始化成功则返回true,否则返回false */
60 /************************************************************************/
61
62 al_init_font_addon();
63 al_init_ttf_addon();
64 al_install_mouse();
65 al_install_keyboard();
66 /************************************************************************/
67 /* 初始化鼠标,和键盘设备,以便Allegro可以接收到鼠标和键盘消息 */
68 /************************************************************************/
69
70 //al_set_new_display_flags(ALLEGRO_FULLSCREEN);//如果取消掉本行注释就是全屏模式
71 display = al_create_display(WIN_WIDTH, WIN_HEIGHT);
72 if (!display)return 2;
73 /************************************************************************/
74 /*ALLEGRO_DISPALY *al_create_display(int w,int h) 创建显示设备
75 参数 w 为要创建的窗口的宽度
76 参悟 h 为窗口的高度
77 成功则返回一个disply的指针,否则返回NULL
78 /************************************************************************/
79 //设置Windows的标题
80 al_set_window_title(display, "Allrgro系列教程(四) 显示文字");
81
82 //初始化事件队列,接受到的消息将存储在该队列里
83 queue = al_create_event_queue();
84 //指定要接收哪个设备的消息
85 al_register_event_source(queue, al_get_keyboard_event_source());
86 al_register_event_source(queue, al_get_display_event_source(display));
87
88 font=al_load_ttf_font("SIMYOU.TTF",24,0);
89 if(!font)return 3;
90 ustr =al_ustr_new("你好!");
91 if(!ustr)return 4;
92
93 return 0;
94}
95int game_msg(){
96
97 al_wait_for_event(queue,&my_event);
98 /************************************************************************/
99 /* 函数原型
100 void al_wait_for_event(ALLEGRO_EVENT_QUEUE *queue,ALLEGRO_EVENT *ret_event)
101 等到队列里有新事件时,将新事件的内容复制到 ret_event里,并从事件队列里移除它
102 */
103 /************************************************************************/
104 if(my_event.type==ALLEGRO_EVENT_DISPLAY_CLOSE)return 98; //当窗口被关闭时
105 if (my_event.type == ALLEGRO_EVENT_KEY_CHAR) {
106 if (my_event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)//当按下 ESC键时
107 return 99;
108 }
109 return 0;
110
111}
112
113int game_frame(){
114 return 0;
115}
116
117
118
119int game_render(){
120 //用指定的颜色填充屏幕
121 al_clear_to_color(al_map_rgb(0,0,0));
122 //al_draw_text(font,al_map_rgb(255,0,0),0,0,0,"你好");
123 al_draw_ustr(font,al_map_rgb(255,0,0),0,0,0,ustr);
124 //翻转
125 al_flip_display();
126 return 0;
127}
128
129
130
131int game_run(){
132
133 //下面的变量用来记录时间,单位是秒
134 //用以控制帧率(FPS),也就是每秒画面刷新多少帧,
135 //这里我们设FPS为30,用 1秒的时间单位/FPS
136 //也就是0.033,也就是说,每次刷新的间隔时间不能小于0.033秒
137 double t_now=0.0; //当前时刻
138 double t_pre=0.0;
139 int error=0;
140 while (true)
141 {
142 if(!al_is_event_queue_empty(queue)){ //先检测事件对了中是否有新事件
143
144 error =game_msg(); //有 则先处理事件
145 if(error!=0)return error;
146 }else{
147 //如果 事件队列中没有新事件 则
148 //计算事件间隔时候大于0.033
149 t_now=al_get_time();
150 if(t_now-t_pre>=0.033){
151
152 //如果时间间隔合适的话就
153 //更新一帧的游戏逻辑
154 error=game_frame();
155 if(error!=0)return error;
156 //刷新画面
157 error=game_render();
158 if(error!=0)return error;
159 t_pre=t_now;
160 }else{
161 al_rest(0);
162 }
163 }
164
165 }
166 return 0;
167}
168
169
170int game_distory(){
171 al_destroy_font(font);
172 return 0;
173}
|
Cassio Renan
Member #14,189
April 2012
![]() |
Visual Studio is probably messing with your source file. I had this problem when I still used it(Since then I moved to Code::Blocks, and lived happilly ever after) This is counter-intuitive, but try saving your source file as ANSI encoding(whithout converting it, so chinese characters will appear as gilberish), and compiling again with VC. Worked for me. EDIT: Unfortunately, at the time, this method is the only way I got my language to work properly using MSVC. Check this thread for more info. |
Quanwei Yuan
Member #14,752
December 2012
![]() |
...... 1.Put the "SIMYOU.TTF" file in the same place as the executable. I write in chinese and english a string,but only display endlish part. ustr =al_ustr_new("hello你好!");
|
Peter Wang
Member #23
April 2000
|
Your best options are to move your strings into an external file, or use gcc. The problem is that MSVC converts string literals from the source file encoding (UTF-8) into the local encoding (e.g. GB2312). There are ways to trick it not to do that, but it is not reliable.
|
Quanwei Yuan
Member #14,752
December 2012
![]() |
Thank you very much for your help 1//头文件
2#define ALLEGRO_NO_MAGIC_MAIN
3#include <Windows.h>
4#include <allegro5/allegro.h>
5#include <allegro5/allegro_font.h>
6#include <allegro5/allegro_ttf.h>
7#pragma comment(lib,"allegro-5.0.7-mt-debug.lib") //链接Allegro的库
8#pragma comment(lib,"allegro_font-5.0.7-mt-debug.lib") //链接Allegro的库
9#pragma comment(lib,"allegro_ttf-5.0.7-mt-debug.lib") //链接Allegro的库
10////////////////////////////////////////////////////////////////////////////////////////////
11
12//函数
13int game_init(); //初始化游戏
14int game_run(); //进入游戏循环
15int game_frame(); //逻辑处理函数
16int game_render(); //渲染函数
17int game_distory(); //释放资源
18int game_msg(); //消息处理
19char * UTF8(wchar_t * src,char * str=0,int str_length=0);
20//常量
21const int WIN_WIDTH =800; //窗口宽度
22const int WIN_HEIGHT =600; //窗口高度
23//全局变量
24ALLEGRO_DISPLAY *display; //显示设备
25ALLEGRO_EVENT_QUEUE *queue; //事件队列
26ALLEGRO_EVENT my_event; //事件
27ALLEGRO_FONT *font=0;
28ALLEGRO_USTR *ustr;
29char str[20]={0};
30char* str2=0;
31int outLength;
32////////////////////////////////////////////////////////////////////////////////////////////
33int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd )
34{
35 int error=0;
36
37 //把游戏初始化的代码写在我们的 game_init()函数里
38 //然后放到这里执行
39 //把game_init()的返回值赋给error
40 //error如果为0的话表示一切正常,初始化成功了!
41 //如果不为0的话,表示初始化的时候,发生了意外。
42 //需要立即结束程序,并返回错误码
43 error=game_init();
44 if(error!=0)return error;
45
46
47 //初始化完成后,开始进入游戏的主循环,
48 //在主循环里将循环执行,消息处理,逻辑处理,和渲染函数
49 error=game_run();
50 if(error!=0)return error;
51
52
53 //游戏结束后,销毁所占用的资源
54 error=game_distory();
55 if(error!=0)return error;
56
57 return 0;
58}
59int game_init(){
60
61 if (!al_init())return 1;
62 /************************************************************************/
63 /* 使用al_init()来初始化Allegro系统
64 al_init实际上是一个宏,他实际上调用了
65 al_install_system(ALLEGRO_VERSION_INT,atexit)
66 该函数的返回值是布尔型,初始化成功则返回true,否则返回false */
67 /************************************************************************/
68
69 al_init_font_addon();
70 al_init_ttf_addon();
71 al_install_mouse();
72 al_install_keyboard();
73 /************************************************************************/
74 /* 初始化鼠标,和键盘设备,以便Allegro可以接收到鼠标和键盘消息 */
75 /************************************************************************/
76
77 //al_set_new_display_flags(ALLEGRO_FULLSCREEN);//如果取消掉本行注释就是全屏模式
78 display = al_create_display(WIN_WIDTH, WIN_HEIGHT);
79 if (!display)return 2;
80 /************************************************************************/
81 /*ALLEGRO_DISPALY *al_create_display(int w,int h) 创建显示设备
82 参数 w 为要创建的窗口的宽度
83 参悟 h 为窗口的高度
84 成功则返回一个disply的指针,否则返回NULL
85 /************************************************************************/
86 //设置Windows的标题
87 al_set_window_title(display, "Allrgro系列教程(四) 显示文字");
88
89 //初始化事件队列,接受到的消息将存储在该队列里
90 queue = al_create_event_queue();
91 //指定要接收哪个设备的消息
92 al_register_event_source(queue, al_get_keyboard_event_source());
93 al_register_event_source(queue, al_get_display_event_source(display));
94
95 font=al_load_ttf_font("simfang.ttf",24,1);
96 if(!font)return 3;
97 if(!UTF8(L"我很好啊",str,20))return 5;
98 str2=UTF8(L"hello你好!");
99 return 0;
100}
101int game_msg(){
102
103 al_wait_for_event(queue,&my_event);
104 /************************************************************************/
105 /* 函数原型
106 void al_wait_for_event(ALLEGRO_EVENT_QUEUE *queue,ALLEGRO_EVENT *ret_event)
107 等到队列里有新事件时,将新事件的内容复制到 ret_event里,并从事件队列里移除它
108 */
109 /************************************************************************/
110 if(my_event.type==ALLEGRO_EVENT_DISPLAY_CLOSE)return 98; //当窗口被关闭时
111 if (my_event.type == ALLEGRO_EVENT_KEY_CHAR) {
112 if (my_event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)//当按下 ESC键时
113 return 99;
114 }
115 return 0;
116
117}
118
119int game_frame(){
120 return 0;
121}
122
123
124
125int game_render(){
126 //用指定的颜色填充屏幕
127
128
129 al_clear_to_color(al_map_rgb(0,0,0));
130 al_draw_text(font,al_map_rgb(255,0,0),0,0,0,str);
131 al_draw_text(font,al_map_rgb(255,0,0),0,50,0,str2);
132 //翻转
133 al_flip_display();
134 return 0;
135}
136
137
138int game_run(){
139
140 //下面的变量用来记录时间,单位是秒
141 //用以控制帧率(FPS),也就是每秒画面刷新多少帧,
142 //这里我们设FPS为30,用 1秒的时间单位/FPS
143 //也就是0.033,也就是说,每次刷新的间隔时间不能小于0.033秒
144 double t_now=0.0; //当前时刻
145 double t_pre=0.0;
146 int error=0;
147 while (true)
148 {
149 if(!al_is_event_queue_empty(queue)){ //先检测事件对了中是否有新事件
150
151 error =game_msg(); //有 则先处理事件
152 if(error!=0)return error;
153 }else{
154 //如果 事件队列中没有新事件 则
155 //计算事件间隔时候大于0.033
156 t_now=al_get_time();
157 if(t_now-t_pre>=0.033){
158
159 //如果时间间隔合适的话就
160 //更新一帧的游戏逻辑
161 error=game_frame();
162 if(error!=0)return error;
163 //刷新画面
164 error=game_render();
165 if(error!=0)return error;
166 t_pre=t_now;
167 }else{
168 //当CPU可以处理游戏逻辑的能力超过我们的需要时
169 //调用Sleep(0)
170 //这个Windows API 将使当前的线程释放出自己的控制权,
171 //这一点对Windows平台很重要,可以使游戏不至于占用全部
172 //的CPU,每次切换游戏的进程,都把可以用的时间片用完了
173 al_rest(0);
174 }
175 }
176
177 }
178 return 0;
179}
180
181
182int game_distory(){
183 delete str2;
184 al_destroy_font(font);
185 return 0;
186}
187
188
189
190char * UTF8(wchar_t * src,char * str,int str_length){
191
192 int length =WideCharToMultiByte(CP_UTF8,0,src,-1,NULL,0,0,0);
193 if(str!=0 && str_length!=0){
194 if(str_length<length)return 0;
195 WideCharToMultiByte(CP_UTF8,0,src,-1,str,str_length,0,0);
196 return str;
197 }
198 str=new char[length];
199 WideCharToMultiByte(CP_UTF8,0,src,-1,str,length,0,0);
200 return str;
201
202}
I hope allegro's next version support this function.. |
Thomas Fjellstrom
Member #476
June 2000
![]() |
Just a note, but unless you absolutely need to, there's no reason to use WinMain. Allegro lets you use a normal main() function, even on windows. Using WinMain makes your program less portable. -- |
torhu
Member #2,727
September 2002
![]() |
Quanwei Yuan said: I hope allegro's next version support this function.. It's not hard to make: al_draw_text(const ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, flags, uint16_t const *text) { ALLEGRO_USTR * ustr = al_ustr_new_from_utf16(text); assert(ustr); al_draw_text(font, color, x, y, flags, ustr); al_ustr_free(ustr); }
Untested code, of course http://alleg.sourceforge.net/a5docs/5.0.8/utf8.html#utf-16-conversion |
Elias
Member #358
May 2000
|
Also, never use wchar_t. While wchar_t is UTF16 with MSCV, in general it's not. -- |
Quanwei Yuan
Member #14,752
December 2012
![]() |
torhu: said: It's not hard to make: al_draw_text(const ALLEGRO_FONT *font, ALLEGRO_COLOR color, http://alleg.sourceforge.net/a5docs/5.0.8/utf8.html#utf-16-conversion
Elias said: Also, never use wchar_t. While wchar_t is UTF16 with MSCV, in general it's not.
Thanks! I enjoyed the lively atmosphere of this forum and helpfulness you. I'm hard studying english now. |
|