Java、XML:扩展方法..和JDOM,以灵活的方式构建应用程序



作为一个学习实验,我一直在使用LibGDX创建一个2d java游戏。我在硬编码方面遇到了一个很大的问题,但我一直无法对此采取任何措施。直到最近,我(终于)找到了如何有效地使用sax/dom,然后找到了JDOM。我开始理解,有了像JDOM这样好的API,就可以在使用的每个类中实现用户制造的"Object"(命名为say…"GameObject")。该对象将具有可以构造程序中包含的任何对象的方法。以及一个ArrayList,它将保存所有创建的对象。。。我遇到的问题是,我无法从多个类进行扩展,所以我无法从scene2d中提取"Actor"类并对其进行扩展,以便它能够解析JDOM文档,并填充其数组列表。。。

我的问题是:有没有一种方法可以通过在xml文件中定义对象结构来完全去除对象结构的硬编码,这样可以在运行时更改硬编码的对象数据)

下面是一些示例代码。。。它可能并不完美,但它有望在中得到这个想法

游戏对象。。。这是我希望每个对象都从继承的类

包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抽象层的入口点——这个想法在这里起作用

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
    }
}

游戏屏幕。。。我打算使用的一个对象——这个想法在这里有效。。。正如你所看到的。。。这个对象不需要付出任何努力,超级构造函数是自动生成的,其数组列表的传播自动开始

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>

使用组合而不是继承-让所有对象都包含与成员变量相同的游戏变量。也许为getter指定一个接口,所以:

public interface GameObjectHolder {
    GameObject getGameObject();
}
public class ExampleGO implements GameObjectHolder {
    GameObject go = new GameObject();
    @override
    GameObject getGameObject() {
        return go;
    }
}

现在您只需执行getGameObject.act()、getGameObject.draw()等

如果你需要回调挂钩到GameObject中,使其抽象,然后包含它的对象可以用匿名内部类实现抽象类:

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

相关内容

  • 没有找到相关文章

最新更新