游戏场景需要是可配置的:assetmanager工具类和xml文件读取(代码片段)

zzqm-gamelife zzqm-gamelife     2023-02-21     374

关键词:

我们已经知道,游戏得有个活动场景(每个场景是个可点击的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;
     

 




云镜远程直播限制

...域名解析后,才能正常进行直播推流/播放,具体请参见配置域名CNAME。直播推流 云直播服务不限制推流码率,支持常见分辨率以及对应码率。为避免推流卡顿,建议码率不超过4Mbps。直播播放 直播地址StreamName与推流地址StreamName... 查看详情

为啥 main 方法需要是静态的? [复制]

】为啥main方法需要是静态的?[复制]【英文标题】:Whymainmethodneedstobestatic?[duplicate]为什么main方法需要是静态的?[复制]【发布时间】:2012-12-2811:00:20【问题描述】:可能重复:WhyistheJavamainmethodstatic?JAVA还支持反射JAVA为什么需要m... 查看详情

为啥我要模拟的属性需要是虚拟的?

】为啥我要模拟的属性需要是虚拟的?【英文标题】:WhydoesthepropertyIwanttomockneedtobevirtual?为什么我要模拟的属性需要是虚拟的?【发布时间】:2011-04-1423:35:18【问题描述】:我正在做一些单元测试,并使用Moq模拟一些属性。现在... 查看详情

结构的大小是不是需要是该结构对齐的精确倍数?

】结构的大小是不是需要是该结构对齐的精确倍数?【英文标题】:Isthesizeofastructrequiredtobeanexactmultipleofthealignmentofthatstruct?结构的大小是否需要是该结构对齐的精确倍数?【发布时间】:2011-06-0523:37:35【问题描述】:我再次质疑... 查看详情

为啥在多重继承的情况下QObject需要是第一个

】为啥在多重继承的情况下QObject需要是第一个【英文标题】:WhyQObjectneedstobethefirstincaseofmultipleinheritance为什么在多重继承的情况下QObject需要是第一个【发布时间】:2015-02-2412:00:59【问题描述】:根据http://qt-project.org/doc/qt-4.8/moc.... 查看详情

C++ 原子数组是不是也需要是原子的?

】C++原子数组是不是也需要是原子的?【英文标题】:C++Doesanarrayofatomicsalsoneedtobeatomic?C++原子数组是否也需要是原子的?【发布时间】:2016-11-2922:01:31【问题描述】:我有如下代码:KMessageQueue::KMessageQueue()messages=newatomic<KBuffer*... 查看详情

PHP 到 MySQL 的连接是不是需要是本地的?

】PHP到MySQL的连接是不是需要是本地的?【英文标题】:DoesaPHPtoMySQLconnectionneedtobelocal?PHP到MySQL的连接是否需要是本地的?【发布时间】:2015-01-0304:35:43【问题描述】:好的,我知道这可能是一个非常愚蠢的问题,所以请原谅我... 查看详情

为啥包含 main 方法的类在 Java 中不需要是公共的? [复制]

】为啥包含main方法的类在Java中不需要是公共的?[复制]【英文标题】:Whyaclasscontaingamainmethoddoesn\'tneedtobepublicinJava?[duplicate]为什么包含main方法的类在Java中不需要是公共的?[复制]【发布时间】:2013-09-0804:52:43【问题描述】:我... 查看详情

软工作业2:硬币游戏——代码的分析与改进

...on编码风格指南中译版(GoogleSOC),改进Python程序如何设计游戏规则,使得慈善事业可持续。地铁口放置硬币箱(初始值500硬币),顾客可取、可放。请设计一组规则,使得该钱箱永远有钱取(尽量符合实际)参考:地铁口钱箱作... 查看详情

libgdx之assetmanager资源管理器及进度条的实现

...象,其实就是后台在加载资源了,这时我们需要AssetManager来异步加载资源,同 查看详情

调用 Future 的函数也需要是 Future 吗?

】调用Future的函数也需要是Future吗?【英文标题】:DoesafunctionthatcallsaFutureneedstobeaFuturetoo?【发布时间】:2021-11-2304:35:53【问题描述】:我有一个调用Future的函数。现在我不确定第一个函数是否也需要成为未来来等待数据。这是... 查看详情

jenkins自动化发布方法

...准备1、分支确保自动化发布仓库分支统一,正式环境需要是release,内网测试环境test_release。如果没有的请先新建好。注:release需要是保护分支,因为正式环境不允许随意发布。设置后需要在保护分支设置里面配置其【可合并Pul... 查看详情

为啥在字符串中使用 javascript 转义字符的引号需要是 \\' 而不是 \'

】为啥在字符串中使用javascript转义字符的引号需要是\\\\\\\\\\\'而不是\\\\\\\'【英文标题】:whyusingjavascriptescapecharacterofquotationinstringneedtobe\\\\\'insteadof\\\'为什么在字符串中使用javascript转义字符的引号需要是\\\\\'而不是\\\'【发布时... 查看详情

产品经理(productmanager)工作主要是做什么的?没想到产品经理也分这么多种类型!

目录产品经理职业介绍产品经理职能介绍功能型产品经理运营型产品经理管理型产品经理 查看详情

plist中的NSdictionary对象需要是数组的数组,怎么转换?

】plist中的NSdictionary对象需要是数组的数组,怎么转换?【英文标题】:NSdictionaryobjectinplistneedstobeaarrayofarrays,howtoconvert?【发布时间】:2010-06-2819:39:48【问题描述】:我有一个字典.plist,其中有一个子数组,但是在Json中的转换过... 查看详情

Laravel 5 更新验证电子邮件需要是唯一的

】Laravel5更新验证电子邮件需要是唯一的【英文标题】:Laravel5UpdateValidationemailneedstobeunique【发布时间】:2019-01-2611:44:58【问题描述】:我正在尝试以管理员身份更新用户。我正在更改用户名,但它说电子邮件必须是唯一的。我... 查看详情

为啥在集合视图单元格中以编程方式创建的按钮需要是惰性变量?

】为啥在集合视图单元格中以编程方式创建的按钮需要是惰性变量?【英文标题】:Whydoesabuttoncreatedprogrammaticallyinacollectionviewcellneedtobealazyvar?为什么在集合视图单元格中以编程方式创建的按钮需要是惰性变量?【发布时间】:201... 查看详情

lua无法排序的问题(key需要是连续的)(代码片段)

排序的Key需要是连续的localx=[1]=x=6,[2]=x=5,[3]=x=7,[5]=x=2,[6]=x=8,[7]=x=5---从小到大排序table.sort(x,function(a,b)returna.x<b.xend)fori=1,10doifx[i]~=nilthenprint(x[i].x)endend打印出:5,6,7,2,8,5可以看到后 查看详情