android游戏开发框架libgdx的使用(十九)—使用自定义配置改进AVG游戏开发

转载声明: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 } 

最后贴上效果图,这是我正在做的一个东西:

demo1
demo2
图片分享:


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