android游戏开发框架libgdx的使用(十八)—简单的AVG游戏效果实现

转载声明:http://www.cnblogs.com/htynkn/archive/2012/03/02/libgdx_18.html

好久没有写libgdx的东西了,主要是最近迷上了各种算法…

文章是关于实现简单的AVG游戏效果,可能会有好几篇。

想用libgdx做点AVG效果主要是因为目前Android上运行的AVG游戏(主要是恋爱模拟类型)的基本基于NScripter引擎移植出来的,我的2B中兴机子跑着巨卡,所以想自己做个。

 

何为AVG游戏

冒险类游戏AVG (Adventure Game)通常是玩家控制角色进行虚拟冒险的游戏,其故事情节往往是以完成某个任务或是解开一个谜题的形式出现的。

我这里说的AVG主要是指日式AVG,就是在最初的文字冒险游戏的基础上利用精美的CG图片和动人的音响效果加以强化,靠优秀的文字和剧情打动人心的一种游戏形式。

比如夜明前的琉璃色

20100317110151412

 

简单分析

AVG游戏主要是由对话,CG图和音效组成。

拆分下来其实很简单,如下图

thinking

再看一张:

thinking2

就不举其他例子了,每个场景基本由背景(场景图),对话,人物组成。要是以前玩过的话就很清楚了,背景切换比较少,人物的变化也比较少,文字是点击或者触摸就切换到下一句去。

我是选用的libgdx的Stage,背景和人物做成Image,对话由Label实现,对话边框由NinePatch实现,然后触摸对话框区域就切换到下一句去。

 

文字处理

AVG游戏的对话占据了很大部分,中文的处理很重要。

libgdx支持中文有两种方法,一是使用Hiero制作,二是使用ttf字库(好像目前还有点问题,暂时不推荐使用)。

最全的汉字字库有文字9万余个,但是常用的字并不多(相对于所有文字)。

对比中国大陆、中国台湾和香港特区各自的常用字标准,可以得到3500个常用字,全部做成libgdx用的字体文件。

总共生成12张图,共1.90M

chinese

还是有点大就是了。我比较偏向于先使用这个常用字开发,完成后在重新根据实际使用制作字库。

 

libgdx实现

我选用的是Stage,游戏由Game和Screen控制。新建一个类AVGScreen,实现Screen接口。

1 private Stage stage;  //舞台 
2 private TextureRegion background; //背景 
3 private List<String[]> dialogues; //对话 
4 private BitmapFont bitmapFont; //文字 
5 private NinePatch border; //边框 
6 private int currentSize; //当前对话序号

在show方法中,先实例化Stage,然后添加背景,添加边框,在render方法中修改文字。

chinese

背景是铺满就行了,对话的边框宽度是100%,高度是25%左右。

文字绘制是在边框内部。边框我选用的是

border

具体的拆分如下:

border
图片分享:

label定位的代码:

 1 label.x = border.getLeftWidth() + 10; 
 2 label.y = borderImage.height - border.getTopHeight() - 10; 
 3 
 4 至于触摸切换到下一句在边框添加一个ClickListener就行了。
 5 
 6 borderImage.setClickListener(new ClickListener() {
 7 
 8     @Override 
 9     public void click(Actor actor, float x, float y) { 
10         System.out.println("click"); 
11         if (currentSize < dialogues.size() - 1) { 
12             currentSize++; 
13         } 
14     } 
15 }); 

而List<String[]> dialogues中的数据就是对话数据,由【人物名称】和【对话】组成。

如:

1 List<String[]> list = new ArrayList<String[]>(); 
2 for (int i = 0; i < 10; i++) { 
3     list.add(new String[] { "人物", "这是对话" + i }); 
4 }

AVGScreen完整代码:

  1 package com.cnblogs.htynkn.ui;
  2 
  3 import java.util.List;
  4 
  5 import com.badlogic.gdx.Gdx; 
  6 import com.badlogic.gdx.Screen; 
  7 import com.badlogic.gdx.graphics.Color; 
  8 import com.badlogic.gdx.graphics.GL10; 
  9 import com.badlogic.gdx.graphics.g2d.BitmapFont; 
 10 import com.badlogic.gdx.graphics.g2d.NinePatch; 
 11 import com.badlogic.gdx.graphics.g2d.TextureRegion; 
 12 import com.badlogic.gdx.scenes.scene2d.Actor; 
 13 import com.badlogic.gdx.scenes.scene2d.Stage; 
 14 import com.badlogic.gdx.scenes.scene2d.ui.ClickListener; 
 15 import com.badlogic.gdx.scenes.scene2d.ui.Image; 
 16 import com.badlogic.gdx.scenes.scene2d.ui.Label; 
 17 import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
 18 
 19 public class AVGScreen implements Screen {
 20 
 21     private Stage stage;  //舞台 
 22     private TextureRegion background; //背景 
 23     private List<String[]> dialogues; //对话 
 24     private BitmapFont bitmapFont; //文字 
 25     private NinePatch border; //边框 
 26     private int currentSize; //当前对话序号
 27 
 28     public AVGScreen(TextureRegion background, NinePatch border, 
 29             List<String[]> dialogues) { 
 30         this.background = background; 
 31         this.dialogues = dialogues; 
 32         this.border = border; 
 33         bitmapFont = new BitmapFont(); 
 34     } 
 35     
 36     public AVGScreen(TextureRegion background, NinePatch border, 
 37             List<String[]> dialogues,BitmapFont bitmapFont) { 
 38         this.background = background; 
 39         this.dialogues = dialogues; 
 40         this.border = border; 
 41         this.bitmapFont = bitmapFont; 
 42     }
 43 
 44     @Override 
 45     public void dispose() { 
 46         // TODO Auto-generated method stub
 47 
 48     }
 49 
 50     @Override 
 51     public void hide() { 
 52         // TODO Auto-generated method stub
 53 
 54     }
 55 
 56     @Override 
 57     public void pause() { 
 58         // TODO Auto-generated method stub
 59 
 60     }
 61 
 62     @Override 
 63     public void render(float delta) { 
 64         Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
 65 
 66         ((Label) stage.findActor("label")) 
 67                 .setText(dialogues.get(currentSize)[0] + " : " 
 68                         + dialogues.get(currentSize)[1]);
 69 
 70         stage.act(Gdx.graphics.getDeltaTime()); 
 71         stage.draw(); 
 72     }
 73 
 74     @Override 
 75     public void resize(int width, int height) { 
 76         // TODO Auto-generated method stub
 77 
 78     }
 79 
 80     @Override 
 81     public void resume() { 
 82         // TODO Auto-generated method stub
 83 
 84     }
 85 
 86     @Override 
 87     public void show() { 
 88         currentSize = 0;
 89 
 90         stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), 
 91                 false); 
 92         Image backgroundImage = new Image(background); 
 93         backgroundImage.x = backgroundImage.y = 0; 
 94         backgroundImage.setFillParent(true);
 95 
 96         Image borderImage = new Image(border); 
 97         borderImage.x = borderImage.y = 0; 
 98         borderImage.width = Gdx.graphics.getWidth(); 
 99         borderImage.height = Gdx.graphics.getHeight() / 4; 
100         borderImage.setClickListener(new ClickListener() {
101 
102             @Override 
103             public void click(Actor actor, float x, float y) { 
104                 System.out.println("click"); 
105                 if (currentSize < dialogues.size() - 1) { 
106                     currentSize++; 
107                 } 
108             } 
109         });
110 
111         LabelStyle labelStyle = new LabelStyle(bitmapFont, Color.BLACK); 
112         Label label = new Label("", labelStyle, "label"); 
113         label.x = border.getLeftWidth() + 10; 
114         label.y = borderImage.height - border.getTopHeight() - 10; 
115         stage.addActor(backgroundImage); 
116         stage.addActor(borderImage); 
117         stage.addActor(label); 
118         Gdx.input.setInputProcessor(stage); 
119     } 
120 } 

演示效果:

demo

可以看出基本效果是实现了,但是还有一些问题,比如人物的添加还有对话框的美观,而且这段代码是在很烂,不易扩展,没有权责分离。

下一篇文章会介绍人物的添加还有使用配置文件保存对话等数据。

最后来一个黎明前的琉璃色的效果:

demo2


posted @ 2013-02-04 21:16  王世桢  阅读(418)  评论(0)    收藏  举报