遊戲場景需要是可配置的:AssetManager工具類和xml檔案讀取
阿新 • • 發佈:2019-01-11
我們已經知道,遊戲得有個活動場景(每個場景是個可點選的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; }