作为一个学习实验,我一直在使用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() {
}
}