转载声明:http://www.cnblogs.com/htynkn/archive/2012/03/03/libgdx_19.html
先说明一下上一篇文章我使用了多张hiero图的字体绘制,因为我对源码进行了一些修改,本来想这次发出来的,但是我仔细调试了一下,发现对于多图的支持还是有问题,有些字会出现偏移。
这个只有继续尝试了…大家可以考虑使用ttf字库。
然后继续说上一篇,虽然实现了一个简单的效果,但是目前有很多不足。我把AVG游戏需要的资源全部提取出来,放在一个个文件夹中,然后通过配置文件加载这些数据。
libgdx的工具库
com.badlogic.gdx.utils就是libgdx的工具库,支持两种格式xml和json。
我最先倾向于使用json格式,但是反复想了想,虽然json的大小可能要小点,但是没有xml直观好读。
所以还是选择使用xml格式,读取xml文件使用XmlReader。
1 XmlReader reader=new XmlReader();
2 try {
3 Element config=reader.parse(Gdx.files.internal("data/config.xml"));
4 config.get("name"); //获取属性值,如果没有属性值则返回同名child的值
5 config.getAttribute("name"); //获取属性值
6 } catch (IOException e) {
7 e.printStackTrace();
8 }
配置文件格式分析
配置文件需要配置的内容其实就是上一篇我们硬编码进去的东西,有背景、边框、对话等。
我设计的比较随意,不一定是最好的,大家可以参考参考。
1 <?xml version="1.0" encoding="UTF-8"?>
2 <scene>
3 <packfile>pack</packfile>
4 <background>bg1</background>
5 <border>
6 <border-name>border</border-name>
7 <border-left>26</border-left>
8 <border-right>26</border-right>
9 <border-top>31</border-top>
10 <border-bottom>31</border-bottom>
11 </border>
12 <dialogues>
13 <dialogue>
14 <name>人物1</name>
15 <data>这是对话1</data>
16 </dialogue>
17 <dialogue>
18 <name>人物1</name>
19 <data>这是对话2</data>
20 </dialogue>
21 </dialogues>
22 </scene>
如果对话比较长还可以继续添加<dialogue>节点。border-*那4个值就是NinePatch的左边距、右边距、上边距、下边距。
这里还有一个地方需要注意,如果我们需要切换场景怎么办?切换的场景可能是一个AVG场景,也可能是个一般的Screen。我本来想做个简单的IOC容器的,但后来想想也没有那么复杂。
在配置文件中加上一句
如果是一般Screen就是
<nextscreen type="standard">com.cnblogs.htynkn.screen.GameOver</nextscreen>
如果是AVG场景就是
<nextscreen type="avg">data/scene2/config.xml</nextscreen>
使用libgdx实现相关效果
其实整个原理和上一篇原理是一样的,唯一多的一个就是解析配置文件和场景跳转。
1 XmlReader xmlReader = new XmlReader();
2 try {
3 Element config = xmlReader.parse(Gdx.files
4 .internal(this.configFileName)); //加载配置文件
5 atlas = new TextureAtlas(Gdx.files.internal(configFileName)
6 .parent()
7 + "/" + config.get("packfile")); //获取pack配置文件
8 background = atlas.findRegion(config.get("background")); //创建背景图
9 Element borderConfig = config.getChildByName("border"); //获取border配置
10 border = new NinePatch(atlas.findRegion(borderConfig.getChild(0)
11 .getText()), Integer.parseInt(borderConfig.getChild(1)
12 .getText()), Integer.parseInt(borderConfig.getChild(2)
13 .getText()), Integer.parseInt(borderConfig.getChild(3)
14 .getText()), Integer.parseInt(borderConfig.getChild(4)
15 .getText())); //实例化border
16 dialogues = new ArrayList<String[]>();
17 Element dialoguesConfig = config.getChildByName("dialogues"); //开始处理对话
18 for (int i = 0; i < dialoguesConfig.getChildCount(); i++) {
19 dialogues.add(new String[] {
20 dialoguesConfig.getChild(i).get("name"),
21 dialoguesConfig.getChild(i).get("data") });
22 }
23 Element screenConfig = config.getChildByName("nextscreen"); //处理场景
24 if (screenConfig.getAttribute("type").equals("avg")) {
25 nextScreen = new AVGScreen(this.game, screenConfig.getText());
26 } else {
27 try {
28 nextScreen = (Screen) Class.forName(screenConfig.getText())
29 .newInstance();
30 } catch (Exception e) {
31 e.printStackTrace();
32 }
33 }
34
35 } catch (IOException e) {
36 e.printStackTrace();
37 }
读取完成后构建舞台,然后绘制。唯一需要修改的就是场景跳转。
1 borderImage.setClickListener(new ClickListener() {
2
3 @Override
4 public void click(Actor actor, float x, float y) {
5 if (currentSize < dialogues.size() - 1) {
6 currentSize++;
7 } else {
8 if (nextScreen != null) {
9 game.setScreen(nextScreen);
10 }
11 }
12 }
13 });
完整代码:
1 package com.cnblogs.htynkn.ui;
2
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.List;
6
7 import com.badlogic.gdx.Game;
8 import com.badlogic.gdx.Gdx;
9 import com.badlogic.gdx.Screen;
10 import com.badlogic.gdx.graphics.Color;
11 import com.badlogic.gdx.graphics.GL10;
12 import com.badlogic.gdx.graphics.Texture;
13 import com.badlogic.gdx.graphics.g2d.BitmapFont;
14 import com.badlogic.gdx.graphics.g2d.NinePatch;
15 import com.badlogic.gdx.graphics.g2d.TextureAtlas;
16 import com.badlogic.gdx.graphics.g2d.TextureRegion;
17 import com.badlogic.gdx.scenes.scene2d.Actor;
18 import com.badlogic.gdx.scenes.scene2d.Stage;
19 import com.badlogic.gdx.scenes.scene2d.ui.ClickListener;
20 import com.badlogic.gdx.scenes.scene2d.ui.Image;
21 import com.badlogic.gdx.scenes.scene2d.ui.Label;
22 import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
23 import com.badlogic.gdx.utils.Array;
24 import com.badlogic.gdx.utils.XmlReader;
25 import com.badlogic.gdx.utils.XmlReader.Element;
26
27 public class AVGScreen implements Screen {
28
29 private String configFileName;
30 private Stage stage; // 舞台
31 private List<String[]> dialogues; // 对话
32 private BitmapFont bitmapFont; // 文字
33 private NinePatch border; // 边框
34 private int currentSize; // 当前对话序号
35 private TextureAtlas atlas;
36 private TextureRegion background;
37 private Screen nextScreen;
38 private Game game;
39
40 public AVGScreen(Game game, String configFileName) {
41 this.game = game;
42
43 bitmapFont = new BitmapFont(Gdx.files.internal("font/chinese.fnt"),
44 false);
45
46 this.configFileName = configFileName;
47 XmlReader xmlReader = new XmlReader();
48 try {
49 Element config = xmlReader.parse(Gdx.files
50 .internal(this.configFileName));
51 atlas = new TextureAtlas(Gdx.files.internal(configFileName)
52 .parent()
53 + "/" + config.get("packfile"));
54 background = atlas.findRegion(config.get("background"));
55 Element borderConfig = config.getChildByName("border");
56 border = new NinePatch(atlas.findRegion(borderConfig.getChild(0)
57 .getText()), Integer.parseInt(borderConfig.getChild(1)
58 .getText()), Integer.parseInt(borderConfig.getChild(2)
59 .getText()), Integer.parseInt(borderConfig.getChild(3)
60 .getText()), Integer.parseInt(borderConfig.getChild(4)
61 .getText()));
62 dialogues = new ArrayList<String[]>();
63 Element dialoguesConfig = config.getChildByName("dialogues");
64 for (int i = 0; i < dialoguesConfig.getChildCount(); i++) {
65 dialogues.add(new String[] {
66 dialoguesConfig.getChild(i).get("name"),
67 dialoguesConfig.getChild(i).get("data") });
68 }
69 Element screenConfig = config.getChildByName("nextscreen");
70 if (screenConfig.getAttribute("type").equals("avg")) {
71 nextScreen = new AVGScreen(this.game, screenConfig.getText());
72 } else {
73 try {
74 nextScreen = (Screen) Class.forName(screenConfig.getText())
75 .newInstance();
76 } catch (Exception e) {
77 e.printStackTrace();
78 }
79 }
80
81 } catch (IOException e) {
82 e.printStackTrace();
83 }
84 }
85
86 @Override
87 public void dispose() {
88 bitmapFont.dispose();
89 stage.dispose();
90 }
91
92 @Override
93 public void hide() {
94 // TODO Auto-generated method stub
95
96 }
97
98 @Override
99 public void pause() {
100 // TODO Auto-generated method stub
101
102 }
103
104 @Override
105 public void render(float delta) {
106 Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
107
108 ((Label) stage.findActor("label"))
109 .setText(dialogues.get(currentSize)[0] + " : "
110 + dialogues.get(currentSize)[1]);
111
112 stage.act(Gdx.graphics.getDeltaTime());
113 stage.draw();
114 }
115
116 @Override
117 public void resize(int width, int height) {
118 // TODO Auto-generated method stub
119
120 }
121
122 @Override
123 public void resume() {
124 // TODO Auto-generated method stub
125
126 }
127
128 @Override
129 public void show() {
130 currentSize = 0;
131
132 stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(),
133 false);
134 Image backgroundImage = new Image(background);
135 backgroundImage.x = backgroundImage.y = 0;
136 backgroundImage.setFillParent(true);
137
138 Image borderImage = new Image(border);
139 borderImage.x = borderImage.y = 0;
140 borderImage.width = Gdx.graphics.getWidth();
141 borderImage.height = Gdx.graphics.getHeight() / 4;
142 borderImage.setClickListener(new ClickListener() {
143
144 @Override
145 public void click(Actor actor, float x, float y) {
146 if (currentSize < dialogues.size() - 1) {
147 currentSize++;
148 } else {
149 if (nextScreen != null) {
150 game.setScreen(nextScreen);
151 }
152 }
153 }
154 });
155
156 LabelStyle labelStyle = new LabelStyle(bitmapFont, Color.WHITE);
157 Label label = new Label("", labelStyle, "label");
158 label.x = border.getLeftWidth() + 10;
159 label.y = borderImage.height - border.getTopHeight() - 10;
160 stage.addActor(backgroundImage);
161 stage.addActor(borderImage);
162 stage.addActor(label);
163 Gdx.input.setInputProcessor(stage);
164 }
165 }
最后贴上效果图,这是我正在做的一个东西:
图片分享: