| 网站首页 | 业界动态 | 游戏教程 | 佳宾留言 | 游戏屋商城 | 供求信息 | 人力资源 | 
您现在的位置: 游戏屋 >> 游戏教程 >> 程序教程 >> 移动平台 >> 教程正文 用户登录 新用户注册
游戏开发小技巧—低级界面下的文本自动换行            【字体:
游戏开发小技巧—低级界面下的文本自动换行
作者:佚名    教程来源:网络搜集    点击数:    更新时间:2006-5-20    

在应用中,有时候需要显示大段的文字。如游戏中的帮助信息,以及RPG游戏的人物对白。对于这种大量文字的显示,我们会很自然地想到使用高级界面的Form来显示,好处就是简单方便,我们不用去操心文字的断行排版,Form会为你搞定一切。
但是,有时候我们无法使用高级界面,如游戏规定必须使用低级界面,再有就是RPG类的游戏也是必须要使用低级界面来显示对白的。
使用低级界面显示大段文字,关键在于你要把它给排好版。最直接的问题就是:一行可以显示几个字?
很多人这样做:通过真机(必须用真机,模拟器不行的,会有差异)测量好一行能显示几个字,比如说7个。然后把大段的文字分成7个一行,变成了一个字符串数组,如:
final String[] strGameHelp = {
    "年份不详的一个",
    "时代中,妖与人",
    "类都存在于世界",
    "上,并基本为对",
    "立状态,但是不",
    "排除有相处一起",
    "的可能,因为人",
    "类基本已经接受",
    "世界上有妖的事",
    "实了。"
};
有了这么一个字符串数组,我们就可以循环把它画出来:
for(int i=0;i<strGameHelp.length;i++){
  g.drawString(strGameHelp[i],5,5+20*i,Graphics.TOP|Graphics.LEFT);
}
上NOKIA、SE、MOTO几个模拟器一看,恩,不错,很管用,效果很好。当下把几个版本呼啦呼啦就全给搞定了。
当你正要端起杯子喝口水的时候,策划跑了过来
K700的文字怎么出框了
不可能啊,我量好了的,模拟器上看的好好的
不信你看……,策划掏出了K700
你一看,果然出了框,看起来一行只能显示6个字。
无奈,你开始挪字,改成:
final String[] strGameHelp = {
    "年份不详的一",
    "个时代中,妖",
    "与人类都存在",
    "于世界上,并",
    "基本为对立状",
    "态,但是不排",
    "除有相处一起",
    "的可能,因为",
    "人类基本已经",
    "接受世界上有",
    "妖的事实了。"
};
保存,编译,打包发给策划。
但策划拒绝了文件传送。
干吗不收啊,你问。
还要改个东西,加一个字,改成“在年份不详的……”,策划告诉你。
你想了想,问策划:能不能不改?
不能。策划回答的很快,我也不想加的,某某领导要求的。
你无语。准备再开始挪字……
突然想:我不能老是改文字呀,万一下次他跑过来说再加个什么东西怎么办?
得想个法子搞定它。
于是写了个函数:
final int CharacterNumber = 6;
public Vector getSubsection(String str){
  Vector vector = new Vector();
  int i=0;
  while(!str.equals(""){
    if(str.length>6){
      vector.addElement(str.substring(0,CharacterNumber));
      str = str.substring(CharacterNumber);
    }
    else{
      vector.addElement(str);
      str = "";
    }
  }
  return vector;
}
再把帮助信息改一改:
final String strGamehelp =
    "在年份不详的一"+
    "个时代中,妖"+
    "与人类都存在"+
    "于世界上,并"+
    "基本为对立状"+
    "态,但是不排"+
    "除有相处一起"+
    "的可能,因为"+
    "人类基本已经"+
    "接受世界上有"+
    "妖的事实了。";
最后是画出来:
Vector vector = getSubsection(strGamehelp);
for(int i=0;i<vector.size();i++){
  g.drawString((String)vector.elementAt(i),5,5+20*i,Graphics.TOP|Graphics.LEFT);
}
vector = null;
这下好了,随便加,怎么加我都不怕,嘿嘿,自动换行。

到这是不是结束了?还没。
一个月后,你开始做英文版,帮助信息改成了英文。你发现帮助界面是惨不忍睹。
原来,英文字母和中文不一样,它是不等宽字体,有肥有瘦,发育不太均衡。
更重要的是,,英文中一个单词是不能拆开分成两行显示。

怎么办。回过去用高级界面?想都不要想。
你打开API手册查阅,希望能找出点什么来。
有了,你眼前一亮,印入眼帘的正是Font类提供的stringWidth函数,该函数能够返回字符串在屏幕上显示时的长度。
有了这个函数,就可以改进getSubsection函数了
其中,strSource是待断行的文字,font是画文字时使用的字体,width是每行的最大宽度,而最后的strSplit是用于分词的,即英文单词中的间隔符号,函数依靠这个参数来分辨单词。
   public Vector getSubsection(String strSource,Font font,int width,String strSplit){
     Vector vector = new Vector();
     String temp=strSource;
     int i,j;
     int LastLength = 1;
     int step = 0;
     try{
         while (!temp.equals("")) {
           i=temp.indexOf("\n");
           if(i>0){
             if(font.stringWidth(temp.substring(0,i-1)) >= width){
               i = -1;
             }
           }
           if(i==-1){
             if(LastLength>temp.length()){
               i = temp.length();
             }else{
               i = LastLength;
               step = font.stringWidth(temp.substring(0, i)) > width ? -1 : 1;
               if(i<temp.length()){
                 while (! (font.stringWidth(temp.substring(0, i)) <= width
                           && font.stringWidth(temp.substring(0, i + 1)) > width)) {
                   i = i + step;
                   if (i == temp.length())
                     break;
                 }
               }
             }
             if(!strSplit.equals("")){
               j = i;
               if (i < temp.length()) {
                 while (strSplit.indexOf(temp.substring(i-1,i))==-1) {
                   i--;
                   if (i == 0) {
                     i = j;
                     break;
                   }
                 }
               }
             }
           }
           LastLength = i;
           vector.addElement(temp.substring(0, i));
           if (i == temp.length()) {
             temp = "";
           }
           else{
             temp = temp.substring(i);
             if (temp.substring(0, 1).equals("\n")) {
               temp = temp.substring(1);
             }
           }
         }
     }catch(Exception e)
     {
       System.out.println("getSubsection:"+e);
     }
     return vector;
  }

再改一下调用的地方:
Font font  = Font.getFont(Font.FACE_SYSTEM,Font.STYLE_PLAIN, Font.SIZE_SMALL);
g.setFont(font);
Vector vector = getSubsection(strGamehelp,font,getWidth()-10," ,.?!");
这样,对于英文我们也可以正确的自动断行显示了。

终于,你可以坐下来,喝杯水(咖啡被抢光了),听点music,享受一下:
1、通用性好,自动适应不同的屏幕大小,各种语言文字通吃。
2、工作量小,你不用去辛苦手工分行,更不用为了加一个字而全部重新来过。想调整宽度?改一个参数就好。

然而,最最后不得不和你说,千万要注意的是,一定要注意调用函数时使用的字体和实际使用的字体要一致,不然我会错(我常犯这样的错误:))


教程录入:网友提供    责任编辑:游戏屋 
  • 上一篇教程:

  • 下一篇教程:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关教程
  • 像素艺术——手机游戏的表现
  • 关于45度视角游戏的美工绘图
  • 给希望成为游戏美术设计师的
  • J2ME 2D小游戏入门之旅(二)完
  • J2ME 2D小游戏入门之旅(三)控
  • J2ME 2D小游戏入门之旅(四)加
  • J2ME 2D小游戏入门之旅(五)实
  • J2ME 2D小游戏入门之旅(六) 
  • J2ME 2D小游戏入门之旅(七) 
  • J2ME 2D小游戏入门之旅(八)源
  •   网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)