AndEngine - 使用匹配的ID在Level对象/ Entites之间绘制一条线

时间:2013-02-27 15:41:25

标签: java android xml andengine

[编辑4] Nvm我忘了添加:

childInt_id[i] = Integer.parseInt(childString_id[i]);

[编辑3]所以现在我希望能够让父实体拥有多个孩子

 <entity x="640" y="224" type="gamebutton1" id="1" child_id="2, 3"/>

我现在将child_id解析为字符串,通过.split(“,”)将其转换为字符串数组,并将字符串数组转换为int数组

final String child_id = SAXUtils.getAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_CHILD_ID);
String[] childString_id = child_id.split(",");
int[] childInt_id = new int[childString_id.length];

我已将levelObjectUserData中的ChildID声明为数组

public int[] ChildID = {-1};

我循环遍历ButtonSpriteChild数组以查看它是否与ButtonSpriteID匹配

for (int k = 0; k < ButtonSpriteChild.length; k++){
if (ButtonSpriteChild[k] == ButtonSpriteID){ ... } }

我在运行游戏时没有遇到任何错误,但现在实体之间没有划线。我想问我是否遗漏了什么? 顺便说一下,这就是我画线的方式:

float parentX = levelObjects.get(i).getX();
float parentY = levelObjects.get(i).getY();
float childX = levelObjects.get(j).getX();
float childY = levelObjects.get(j).getY();
Line line = new Line(parentX, parentY, childX, childY, 10,vbom);
line.setColor(Color.GREEN);
attachChild(line);

[编辑2]:非常感谢史蒂夫的帮助!还有一件事可以请你在答案的最后一点扩展一点 - “现在你解析了XML ...”后,我无法理解你的例子“((levelObjectUserData)(levelObjects.get(i).getUserData ())。。ChildID“,当我尝试使用它时,我收到以下错误:”语法错误,插入“AssignmentOperator表达式”以完成表达式“。再次非常感谢你的帮助

[编辑]:我已经弄清楚我的问题的第一部分xml文件中的一些实体缺少id和child_ids,并添加那些修复了错误。

所以我的问题变成了,如何使用“id”和“child_id”在两个实体之间画一条线。因此,一旦匹配了两个级别的对象,我需要获取父实体的x和y值以及子实体的x和y值,以便可以在它们之间绘制一条线,即

<entity x="640" y="224" type="gamebutton1" id="1" child_id="2"/> 
<entity x="512" y="224" type="gamebutton2" id="2"/>
Line line = new Line(parentX, parentY, childX, childY, 5, vbom);

所以我正在解析levelObjects

levelLoader.registerEntityLoader(new EntityLoader<SimpleLevelEntityLoaderData>(TAG_ENTITY) {

        @Override
        public IEntity onLoadEntity(String pEntityName, IEntity pParent, Attributes pAttributes, SimpleLevelEntityLoaderData pEntityLoaderData) throws IOException {
            final int x = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_X);
            final int y = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_Y);
            final String type = SAXUtils.getAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_TYPE);
            final int id = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_ID);
            final int child_id = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_CHILD_ID);

            final ButtonSprite levelObject;

            if (type.equals(TAG_ENTITY_ATTRIBUTE_VALUE_GAMEBUTTON1)) {
                levelObject = new ButtonSprite(x, y, resourcesManager.gamebutton1_region, vbom, new OnClickListener() {

                    @Override
                    public void onClick(ButtonSprite pButtonSprite, float pTouchAreaLocalX, float pTouchAreaLocalY) {                           

                    }
                });
            }

            else if (type.equals(TAG_ENTITY_ATTRIBUTE_VALUE_GAMEBUTTON2)) {
                levelObject = new ButtonSprite(x, y, resourcesManager.gamebutton2_region, resourcesManager.gamebuttonpressed_region, vbom, new OnClickListener() {

                    @Override
                    public void onClick(ButtonSprite pButtonSprite, float pTouchAreaLocalX, float pTouchAreaLocalY) {

                    }
                });
            }

            else if (type.equals(TAG_ENTITY_ATTRIBUTE_VALUE_GAMEBUTTON3)) {
                levelObject = new ButtonSprite(x, y, resourcesManager.gamebutton3_region, resourcesManager.gamebuttonpressed_region, vbom, new OnClickListener() {

                    @Override
                    public void onClick(ButtonSprite pButtonSprite, float pTouchAreaLocalX, float pTouchAreaLocalY) {

                    }
                });
            }

            else if (type.equals(TAG_ENTITY_ATTRIBUTE_VALUE_GAMEBUTTON4)) {
                levelObject = new ButtonSprite(x, y, resourcesManager.gamebutton4_region, resourcesManager.gamebuttonpressed_region, vbom, new OnClickListener() {

                    @Override
                    public void onClick(ButtonSprite pButtonSprite, float pTouchAreaLocalX, float pTouchAreaLocalY) {

                    }
                });
            }

            else if (type.equals(TAG_ENTITY_ATTRIBUTE_VALUE_GAMEBUTTON5)) {
                levelObject = new ButtonSprite(x, y, resourcesManager.gamebutton5_region, resourcesManager.gamebuttonpressed_region, vbom, new OnClickListener() {

                    @Override
                    public void onClick(ButtonSprite pButtonSprite, float pTouchAreaLocalX, float pTouchAreaLocalY) {

                    }
                });
            }

            else if (type.equals(TAG_ENTITY_ATTRIBUTE_VALUE_GAMEBUTTON6)) {
                levelObject = new ButtonSprite(x, y, resourcesManager.gamebutton6_region, resourcesManager.gamebuttonpressed_region, vbom, new OnClickListener() {

                    @Override
                    public void onClick(ButtonSprite pButtonSprite, float pTouchAreaLocalX, float pTouchAreaLocalY) {

                    }
                });
            }

            else {
                throw new IllegalArgumentException();
            }

            levelObject.setCullingEnabled(true);
            registerTouchArea(levelObject);
            setTouchAreaBindingOnActionDownEnabled(true);
            return levelObject;
        }
    });

基于此我假设得到父x和y,我会简单地使用final int x和final int y,但是我不知道如何能够得到孩子x和y。 我希望我能够澄清我的问题

1 个答案:

答案 0 :(得分:1)

你可以选择,

1)您可以在每个实体中加载时动态执行此操作,但需要确保先前已创建对child_id指向的其他实体的引用。根据您的XML判断并非如此,您的第一个实体的child_id,2指向尚未创建的第二个实体,因此您无法加入当前正在处理的实体(1)与之间的一条线。因此,要做到这一点,您需要重新组织XML,并从最初没有绘制到另一行的实体开始。

或2)一旦创建了所有实体,你就会仔细检查它们并相应地绘制线条,我认为这样会更好,因为无论你将它们放在XML中的顺序都无关紧要。

如果您选择了选项,您需要能够为每个创建的ButtonSprite,ID以及ChildID恢复信息。为此,您还需要一个指向每个ButtonSprite的指针来恢复信息。< / p>

您可以将ID和ChildID放在Sprite的用户数据中,即

创建一个名为levelObjectUserData的类或具有两个公共整数字段ID和ChildID的东西。默认情况下将它们设置为-1。即,

public class levelObjectUserData {
    public int ID = -1;
    public int ChildID = -1;
}

然后对于您在加载器中创建的每个levelObject,即

之后
levelObject.setCullingEnabled(true);

如下所示:

final levelObjectUserData MyData = new levelObjectUserData ();
MyData.ID = id;
MyData.ChildID = child_id;
levelObject.setUserData(MyData);

现在,将每个levelObject添加到某种列表中(我使用链表)。即,

之外
levelLoader.registerEntityLoader...

声明您的链接列表

LinkedList<Shape> levelObjects = new LinkedList<Shape>();

然后,每次在装载程序中创建一个时,将其添加到列表中,即在

之后
levelObject.setCullingEnabled(true);

将levelObject添加到列表中,

levelObjects.add(levelObject);

现在解析完XML后,在加载器完成后,您可以通过遍历链表并在它们之间绘制线来访问您创建的每个levelObject。通过获取该项目的用户数据,您可以轻松地从当前levelObject中找到要绘制线条的按钮精灵,即

for (int i = 0;i<levelObjects.size();i++)
{

        final int ButtonSpriteChild  = ((levelObjectUserData) (levelObjects.get(i).getUserData())).ChildID;
        for (int j = 0;j<levelObjects.size();j++)
        {
            final int ButtonSpriteID = ((levelObjectUserData) (levelObjects.get(j).getUserData())).ID;

            if (ButtonSpriteChild  == ButtonSpriteID)
            {
                //Draw your line here between ButtonSprite levelObjects.get(i)
                //and ButtonSprite levelObjects.get(j) - the child that matches up
            }
        }

}

(其中i是介于0和levelObjects.size()之间的值 - 1)

然后找到精灵按钮,其ID再次与列表中的ChildID相匹配(假设它仍然没有默认值-1)。

你得到了孩子x和y,因为这些是Sprite创建时的初始位置。从链接列表中引用子Sprite后,只需调用

即可
levelObjects.get(j).getInitialX()...
levelObjects.get(j).getInitialy()...

其中j是子Sprite的索引。

希望这有帮助。