使用AndEngine GLES2开发游戏中精灵(Sprite)的最佳实践

11

目前我正在将所有的精灵引用静态化,并在SimpleBaseGameActivity的OnCreateResource方法中加载和初始化它们。但现在我需要覆盖精灵的onAreaTouched监听器,而我想要覆盖它的方法是在初始化精灵时。但我有一个静态方法为每个精灵创建Atlas和Texture Region。我在我的场景类中使用这些精灵,并希望在那里覆盖onAreaTouched方法。我可以在场景中为特定的精灵注册TouchArea,但我希望以一种方式覆盖OnAreaTouched,以便可以实现代码的可重用性。 以下是我当前的精灵创建和加载方式。

defualtCageSprite = createAndLoadSimpleSprite("bg.png", this, 450, 444);

这是我的 createAndLoadSimpleSprite 方法。

public static Sprite createAndLoadSimpleSprite(String name,
        SimpleBaseGameActivity activity, int width, int height) {

    BitmapTextureAtlas atlasForBGSprite = new BitmapTextureAtlas(
            activity.getTextureManager(), width, height);
    TextureRegion backgroundSpriteTextureRegion = BitmapTextureAtlasTextureRegionFactory
            .createFromAsset(atlasForBGSprite, activity, name, 0, 0);
    Sprite sprite = new Sprite(0, 0, backgroundSpriteTextureRegion,
            activity.getVertexBufferObjectManager());
    activity.getTextureManager().loadTexture(atlasForBGSprite);

    return sprite;
}

现在我该如何在不失去代码可重用性的情况下,为一些精灵(sprite)覆盖(onAreaTouched)方法。

2个回答

8
有没有必要在运行时加载纹理?通常的方法是在加载应用程序时将所需的纹理全部加载到单个贴图集中,以便稍后可以快速使用它们。至于代码可重用性,Todilo提出的枚举想法似乎正是您所需要的。例如,假设您有两种对象 - 触摸后消失的对象和触摸后飞起来的对象。您对这两个类别进行枚举,并将一段代码放入触摸事件处理代码中,检查对象是否应该消失或飞起来。如果在运行应用程序之前不知道对象在触摸时应该执行什么操作,则可以通过一种更动态的方式实现相同的结果。只需在运行时创建两个列表,并根据对象在触摸时应执行的操作将对对象的引用放入其中一个列表。然后在触摸事件处理中执行类似以下内容的操作:
if (disappearList.contains(touchedObject)) {
    disappear(object)
}
if (flyUpList.contains(touchedObject)) {
    flyUp(object)
}

很遗憾,AndEngine不允许用户在精灵上设置监听器,这会使事情变得更容易一些。

编辑: 添加了有关使用BlackPawnTextureBuilder的说明: 您的图集必须是BuildableBitmapTextureAtlas类型,然后像这样添加所有纹理

BitmapTextureAtlasTextureRegionFactory.createFromAsset(buildableAtlas, this, "image.png"));

并且在此之后。
try {
    this.buildableAtlas.build(new BlackPawnTextureBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(1));
} catch (final TextureAtlasSourcePackingException e) {
    Debug.e(e);
}

我不知道这是否适用于动画精灵,你需要尝试一下。 此外,没有覆盖onTouch的方法,你需要在onAreaTouched方法中进行处理。一个这样的条件示例是

if (pSceneMotionEvent.getAction() == MotionEvent.ACTION_DOWN && disappearList.contains(pTouchArea)) {disappear();}

1
如果我将所有所需的纹理加载到单个图集中,那么图集的大小应该是多少呢?使用单个图集的好处是什么?顺便问一下,您所说的运行时是什么意思?我在引擎的createResources中初始化所有精灵,然后在应用程序中稍后使用它们。 - Waqas
1
我不仅需要在onTouch上对精灵进行动画处理,还需要根据不同的精灵调用我的模型的不同方法。 - Waqas
1
图集的大小取决于您使用的图像大小,例如,我需要1024x512。好处是内存消耗更小,渲染速度更快。运行时是指应用程序运行时的时间。您可以使用BlackPawnTextureBuilder将纹理放置在图集上,这样您就不必手动执行此操作。使用我的方法,您可以做任何想做的事情,它不受动画精灵的限制。 - JohnEye
在使用简单的BitmapTextureAtlas之前,我曾经使用过BuildableBitmapTextureAtlas,但是我的动画精灵没有显示出来,它只是场景上的一张黑色图片。然后我将BuildableBitmapTextureAtlas更改为BitmapTextureAtlas,并且没有使用BlackPawnTextureBuilder,所有的问题都解决了。现在一切都正常工作。我对代码的可重用性有所担忧。 - Waqas
但是,您必须手动指定地图上的位置,是吗?让构建器为您完成这项工作将节省大量精力,我认为实现它是值得花费时间的。无论如何,我的答案的最后一行是我可以提供的关于代码可重用性的最佳解决方案。否则,您将不得不修改引擎以添加可重用的侦听器到Sprites中。 - JohnEye
显示剩余4条评论

0
你确定不需要比覆盖ontouch更多的功能吗?那对于需要重写onarea和其他所有需求的人来说,创建一个继承自sprite的类如何?

我不能为每个精灵单独创建一个类。我需要在每个精灵的onTouch事件上提供不同的实现。 - Waqas
那我想不出一个好的方法,它不会使实现变得混乱。这取决于实现方式,但是假设您有一组类型的枚举,那么也许onareatouch可以由此确定。所有其他解决方案(例如使用某种命令模式的变体来将方法作为参数传递)似乎有点过度设计,不幸的是。我知道你在尝试做什么,但不幸的是,我没有解决方案可以提供。 - Todilo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接