我们已经知道,游戏得有个活动场景(每个场景是个可点击的button控件),并且可以通过代码生成控件的方式把活动场景进行多行多列的排列。见上篇:https://www.cnblogs.com/zzqm-gamelife/p/10254466.html
但是没有解决这样的问题:
1.场景名称需要自定义
2.版本更新,今天要加个“蟠桃园”的地图,明天活动,又加个“九重妖塔”。
如果每次加个地图就要改一次代码,太麻烦了。我们选择用xml文件来做配置(PS,有条件的可以用服务器和数据库存储,这个我们另外再说)。
fight_scene.xml 大致如下:
<?xml version="1.0" encoding="utf-8"?> <resources> <fight_scene id="1"> <name>永安镇</name> <remark>和平安宁的小镇,故事开始的地方</remark> </fight_scene> <fight_scene id="2"> <name>沉香溪</name> </fight_scene> <fight_scene id="3"> <name>白桦林</name> </fight_scene> ...... </resources>
通过读取配置文件中的数据,并实例化对应的FightScene对象。
首先,我们需要AssetManager工具类找到所需要的xml文件。AssetManager工具类的默认目录为main下面的assets文件夹下,如果默认没有,自己创建一个即可。并将文件转为为io流。
AssetManager assetManager = this.getAssets(); InputStream is = assetManager .open(fileName);
我们采用XmlPullParse这个工具类来读取fight_scene.xml的数据,代码如下:
//打开活动场景配置文件
XmlPullParser xmlParser= Xml.newPullParser(); xmlParser.setInput(is,"utf-8"); int eventType=xmlParser.getEventType(); //定义活动场景及要添加到列表中的活动场景 List<FightScene> lFScene = new ArrayList<FightScene>();
FightScene fightScene=null; while(eventType!=XmlPullParser.END_DOCUMENT){ switch(eventType){ case XmlPullParser.START_DOCUMENT: break; case XmlPullParser.START_TAG: //从io流中读取到活动场景开始的标签 if(xmlParser.getName().equals("fight_scene")) //初始化活动场景 fightScene=new FightScene(); fightScene.setId(Integer.parseInt(xmlParser.getAttributeValue(0))); //getAttributeValue方法读取节点属性 }else if(xmlParser.getName().equals("name")){ fightScene.setName(xmlParser.nextText()); //next方法读取子节点的内容 }else if(xmlParser.getName().equals("remark")){ fightScene.setRemark(xmlParser.nextText()); } break; case XmlPullParser.END_TAG: //从io流中读取到活动场景结束的标签,将赋值后的活动场景添加到列表中 if(xpp.getName().equals("fight_scene")){ lFscene.add(fightScene); } break; } eventType=xpp.next(); }
通过上面的方法,我们将获取到的场景的数据就存储到了队列 lFScene中。
接下来,将生成控件的做对应的调整,就可以在生成场景的button控件时进行赋值了。
@Override
protected void onCreate(Bundle savedInstanceState) {
......
//获取场景列表,生成页面各元素
fightSceneLayout.addView(sceneLayout(lFscene),4);
}
/**
* @param lFscene 活动场景列表
* @return 返回自定义的场景布局
*/
private LinearLayout sceneLayout(List<FightScene> lFscene,int clomuns){
int sceneNums=lFscene.size();
.....
if (surplus==0) {
//如果能够被整除
//将场景列表中另外存储为多个队列
for (int i = 0; i < rows; i++) {
List<FightScene> lfs_rows = new ArrayList<FightScene>();
for(int j=0; j<clomuns; j++){
lfs_rows.add( lFscene.get( i * clomuns + j - 1 ));
}
sly.addView(rowsLayout(lfs_rows));
}
}else{
//如果不能够被整除
//将场景列表中另外存储为多个队列
int i;
for ( i=0 ; i < rows; i++) {
List<FightScene> lfs_rows = new ArrayList<FightScene>();
for(int j=0; j<clomuns; j++){
lfs_rows.add( lFscene.get( i * clomuns + j ));
}
sly.addView(rowsLayout(lfs_rows));
}
//创建最后剩下的,不足一行的布局
//剩下的单独存储为一个队列
List<FightScene> lfs_surplus = new ArrayList<FightScene>();
for(int k =0;k<surplus;k++){
lfs_surplus.add( lFscene.get( i * clomuns + k - 1 ));
}
sly.addView(rowsLayout(lfs_surplus));
}
return sly;
}
/**
* @param clomunsFscene 单行显示的场景
* @return 返回单行显示的LinearLayout
*/
private LinearLayout rowsLayout(List<FightScene> clomunsFscene){
int clomuns= clomunsFscene.size();
......
//循环添加场景button控件
for (int j = 0; j < clomuns; j++) {
Button b_scene = new Button(this);
//设置场景按钮的id和名称
b_scene.setText(clomunsFscene.get(j).getName());
b_scene.setId(clomunsFscene.get(j).getId());
//绑定点击事件
b_scene.setOnClickListener(clickListener);
//添加到创建的线性布局中
rl.addView(b_scene);
}
//添加到显示的父线性布局中
return rl;
}