2013-12-14 46 views
0

作爲一個學習實驗,我一直在使用LibGDX創建一個2D遊戲。硬編碼有一個很大的問題,但是從來沒有做過任何事情。直到最近我(終於)想出瞭如何有效地使用sax/dom,然後找到了JDOM。我開始理解,使用像JDOM這樣的良好API,在每個使用的類中實現一個用戶創建的「Object」(名爲say ...「GameObject」)是非常可能的。這個對象會有可以構造程序中包含的任何對象的方法。以及一個ArrayList,它可以容納所有創建的對象...我遇到的問題是我無法從多個類繼承,所以我沒有辦法從scene2d中取出Actor類並擴展它,它可以解析JDOM文檔,並填充它的ArrayList ...Java,XML:擴展方法...和JDOM以靈活的方式構建應用程序?

我的問題是這樣的:有沒有辦法通過在xml文件中定義對象數據來完全刪除對象結構的硬編碼,被硬編碼在運行時可以改變)

這裏是一些示例代碼......它可能並不完美,但它有望跨越

遊戲物體的想法......這是類希望每個對象繼承自

package rastek.thegame;

import java.util.ArrayList; 
import java.util.List; 
import org.jdom2.Element; 

public class GameObject 
{ 
    Element node; 
    ArrayList<GameObject> gameObjects; 

    public GameObject(Element node) 
    { 
     this.setNode(node); 
     this.parseJDOM(); 
    } 

    public void parseJDOM() 
    { 
     List objectList = this.getNode().getChildren(); 
     for (int i = 0; i < objectList.size(); i++) 
     { 
      Element node = (Element) objectList.get(i); 

      // ONE list of EVERY object used, 
      if (node.getName() == "GameScreen") 
      { 
      //the idea being that since every onject extends gameobject, 
      //they would all take an element as an argument and automatically 
      //create its array structure with it 
       this.getGameObjects().add(new GameScreen(node)); 
      } 

//   if (node.getName() == "GameActor") 
//   { 
//    this.getGameObjects().add(new GameActor(node)); 
//   } 


     } 
    } 

    public Element getNode() 
    { 
     return node; 
    } 

    public void setNode(Element node) 
    { 
     this.node = node; 
    } 

    public ArrayList<GameObject> getGameObjects() 
    { 
     return gameObjects; 
    } 

    public void setGameObjects(ArrayList<GameObject> gameObjects) 
    { 
     this.gameObjects = gameObjects; 
    } 
} 

GameCore ...入口點的libgdx抽象layer--的想法在這裏工作

package rastek.thegame; 

import org.jdom2.Document; 
import org.jdom2.Element; 
import org.jdom2.input.SAXBuilder; 
import com.badlogic.gdx.ApplicationListener; 
import com.badlogic.gdx.Gdx; 



public class GameCore extends GameObject implements ApplicationListener 
{ 
    public GameCore(Element node) 
    { 
     //call the super cunstructor, thus parsing the JDOM and creating 
     //(as per the linked xml), one GameScreen and adding it to the 
     //super's array named gameObjects 

     //unlike the other objects constructors, this is passed a local method, which 
     //is simply a temporary solution to obtain the xml file, 

     //as i dont want platform 
     //dependancy to come into play yet, i dont want to pass the element to GameCore 
     //which comes from the application entry point, which can be android, 
     //ios, or desktop dependant 
     super(createJDOM()); 
    } 



    // currently a local static and (UGH) hardcoded method, may find another 
    // place and implementation for this for this 
    private static Element createJDOM() 
    { 
     Object object = null; 
     Document document; 
     try 
     { 
      SAXBuilder saxBuilder = new SAXBuilder(); 
      object = saxBuilder.build(Gdx.files.internal("data/xml/GameCore.xml").reader()); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
     if (object != null) 
     { 
      document = (Document) object; 
      return document.getRootElement(); 
     } 
     else 
     { 
      return null; 
     } 
    } 
    @Override 
    public void create() 
    { 
    } 
    @Override 
    public void resize(int width, int height) 
    { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void render() 
    { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void pause() 
    { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void resume() 
    { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void dispose() 
    { 
     // TODO Auto-generated method stub 
    } 
} 

GameScreen ......我打算use--的想法對象中的一個在這裏工作。 ..你可以看到...這個對象不需要努力使,超級構造函數是自動生成和ArrayList中的傳播會自動開始

package rastek.thegame; 

import org.jdom2.Element; 
import com.badlogic.gdx.Screen; 

public class GameScreen extends GameObject implements Screen 
{ 

    public GameScreen(Element node) 
    { 
     super(node); 
    } 

    @Override 
    public void render(float delta) 
    { 
    } 

    @Override 
    public void resize(int width, int height) 
    { 
    } 

    @Override 
    public void show() 
    { 
    } 

    @Override 
    public void hide() 
    { 
    } 

    @Override 
    public void pause() 
    { 
    } 

    @Override 
    public void resume() 
    { 
    } 

    @Override 
    public void dispose() 
    { 
    } 
} 

你好

package rastek.thegame; 
import com.badlogic.gdx.scenes.scene2d.Actor; 

public class GameActor extends Actor // ,GameObject 
{ 
    ///i cant extend GameObject on this class, and thus cant add things 
    //like texture objects, and wrappers for complex character data 
} 

,並使用XML IM ...簡單的測試儀

<?xml version="1.0" encoding="UTF-8"?> 
<GameCore> 

    <GameScreen> 
     <Actor> 
      <foo> 
       <bar etc="123" > 
       </bar> 
      </foo> 
     </Actor> 
    </GameScreen> 

</GameCore> 

回答

0

使用組成,而不是繼承 - 把所有的對象包括相同的遊戲變量作爲一個成員變量。也許指定接口,爲吸氣,所以:

public interface GameObjectHolder { 
    GameObject getGameObject(); 
} 

public class ExampleGO implements GameObjectHolder { 

    GameObject go = new GameObject(); 

    @override 
    GameObject getGameObject() { 
     return go; 
    } 
} 

現在,你可以做getGameObject.act(),getGameObject.draw()等

如果你需要回調掛鉤到遊戲物體使它抽象然後,將包含對象時,它可以實現與匿名內部類的抽象類:

GameObject go = new GameObject() { 
     void doStuff() { 
     } 
    } 
+0

不完全是我的意思是......我需要能夠讓所有能夠使用的方法'parseJDOM'的對象,但我還需要讓'Actors'能夠調用'act()'和'draw()'......這個想法就是這樣應用程序會變得很大,因此重構就像更改'GameObject'一樣簡單,並且每個從其延伸的文件都顯示變化......如果我在代碼中傳遞變量太多,我必須改變事物像'return go;'到'return go.getFoo(Bar);'在每個.java文件中...... – user2944537

+0

請參閱編輯。是的,你必須按照這種方式來追蹤更多的鏈接,但這不是什麼大問題,它可以讓你擺脫繼承問題。 –