0

我正在尝试创建一个位于 TMXTiledMap 之上的 AndEngine HUD(请耐心等待,我对 AndEngine 很陌生)。首先,为了简单起见,我有一个通过 Android 可绘制对象创建的简单矩形。这个想法是,它将位于屏幕的底部中心并且永远不会移动,即使它下面的地图向各个方向移动也是如此。现在,我要做的就是让那个矩形显示出来。稍后我将向矩形添加其他功能。

我的drawable是这样创建的:

    ?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle" >
        <corners
            android:radius="7dp" />
        <gradient
            android:startColor="#343434"
            android:endColor="#17171717"
            android:angle="270"
            android:useLevel="false"
            android:type="linear" />
        <padding
            android:left="10dp"
            android:top="10dp"
            android:right="10dp"
            android:bottom="10dp" />
    </shape>

我把它拉成这样的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="300dip"
    android:layout_height="100dip"
    android:orientation="horizontal" 
    android:layout_marginLeft="20dp"
    android:background="@drawable/menu_bkgrnd" >
</LinearLayout>

最后,这里是我尝试将其作为 HUD 引入的地方:

rect = new HUD();
ITouchArea container = (ITouchArea) findViewById(R.id.container);
this.rect.registerTouchArea(container);
rect.attachChild((IEntity) container);

正如你所看到的,我做了很多铸造来满足 AndEngine,但是当我运行这个时,地图完全搞砸了。我这样做对吗?我的选角不正确吗?(或者可能两者兼而有之!)。

谢谢你的帮助。

编辑:根据 Jong 和正宗白布鞋下面建议的代码,我调整了我的 Java 代码如下:

this.atlas = new BitmapTextureAtlas(null, 256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.atlas.load();
ITextureRegion drawable = BitmapTextureAtlasTextureRegionFactory.createFromResource(atlas, getApplicationContext(), R.drawable.myDrawable, 0, 0);
rect.attachChild(new Sprite(0, 0, drawable, this.getVertexBufferObjectManager()));

在这一点上,我仍然只是想让它出现在屏幕上。稍后我会调整大小和位置。

一切都编译并运行没有错误,但是我的屏幕只是一团糟。

如您所见,我必须对构造函数参数进行一些小调整才能让 AndEngine 接受我的实例化。不确定我是否正确执行此操作。

我在这段代码中看到的另一个问题是,在我看来,这段代码只会在我的屏幕上放置一个非活动形状。我知道在我原来的帖子中,我说我的直接目标是让这个矩形显示出来,但我认为它必须显示为一个注册的触摸区域,因为它最终将是一个需要响应的带有控件的东西到用户命令。对不起,如果我过度最小化我正在尝试做的事情。

我仍然没有得到这个。有人有什么建议吗?再次感谢!

4

2 回答 2

2

您不能LinearLayout转换为ITouchArea,ITouchArea是仅由 AndEngine 类实现的接口。

就像正宗白布鞋建议的那样,你应该使用 的createFromResource方法BitmapTextureAtlasTextureRegionFactory

您可以使用以下代码:

BitmapTextureAtlas atlas = new BitmapTextureAtlas(sizeX, sizeY, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
TextureRegion drawable = BitmapTextureAtlasTextureRegionFactory.createFromResource(atlas, getApplicationContext(), R.drawable.drawableId, 0, 0);
rect.attachChild(new Sprite(x, y, drawable));

编辑:

如果您希望您的精灵响应触摸事件,您可以将其注册为rectHUD 中的触摸区域。

Sprite sprite = new Sprite(x, y, drawable, getVertexBufferObjectManager()) {
    @Override
    public boolean onAreaTouched(final TouchEvent pTouchEvent, final float pX, final float pY) {
        //Do what you want here
    }
}
rect.registerTouchArea(sprite);
rect.attachChild(sprite);
于 2012-11-30T12:09:51.983 回答
0

几天前我遇到了同样的问题,但我找不到正确的答案。所以现在我已经从不同的来源收集了信息,这就是我处理这个问题的方法。

AFAIK,似乎createFromResource(atlas, getApplicationContext(), R.drawable.drawableId, 0, 0)from的方法BitmapTextureAtlasTextureRegionFactory无法处理 XML drawable(例如<shape>...</shape>)。
事实上,当我只显示一个彩色矩形时,一切都很好 - 我认为也是 PNG 文件 - 但是当我尝试Sprite从我的 XML 可绘制对象创建一个时,我总是NullBitmapException在绘图发生时得到一个。

我采取的步骤:

  • 将可绘制资源转换为Drawable
  • 转换DrawableBitmap此处来源
  • 转换BitmapTextureRegion(这是我使用的地方)
  • SpriteTextureRegion(或两个用于选定/未选定,如此)创建一个
  • 附加Sprite到游戏的HUD

所以,用代码:

转换可绘制资源TextureRegion

/**
 * Takes a drawable, and converts it to a TextureRegion.
 * @param context
 * @param resId the drawable ID
 * @param textureSizeX width for our TextureRegion
 * @param textureSizeY height for our TextureRegion
 * @return a TextureRegion from the drawable
 */
public static TextureRegion textureRegionFromDrawable(BaseGameActivity context, int resId, int textureSizeX, int textureSizeY) {
    Drawable drawable = context.getResources().getDrawable(resId);
    Bitmap bitmap = drawableToBitmap(drawable);
    BitmapTextureAtlasTextureSource source = new BitmapTextureAtlasTextureSource(bitmap);
    BitmapTextureAtlas textureAtlas = new BitmapTextureAtlas(context.getTextureManager(), textureSizeX, textureSizeY);
    textureAtlas.addTextureAtlasSource(source, 0, 0);
    textureAtlas.load();
    TextureRegion textureRegion = (TextureRegion) TextureRegionFactory.createFromSource(textureAtlas, source, 0, 0);
    return textureRegion;
}
// Drawable to Bitmap
public static Bitmap drawableToBitmap(Drawable drawable) {
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable) drawable).getBitmap();
    }
    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);
    return bitmap;
}

实用中介类

public class BitmapTextureAtlasTextureSource extends BaseTextureAtlasSource implements IBitmapTextureAtlasSource {
    private final int[] mColors;
    public BitmapTextureAtlasTextureSource(Bitmap pBitmap) {
        super(0, 0, pBitmap.getWidth(), pBitmap.getHeight());
        mColors = new int[mTextureWidth * mTextureHeight];
        for (int y = 0; y < mTextureHeight; ++y) {
            for (int x = 0; x < mTextureWidth; ++x) {
                mColors[x + y * mTextureWidth] = pBitmap.getPixel(x, y);
            }
        }
    }
    @Override
    public Bitmap onLoadBitmap(Config pBitmapConfig) {
        return Bitmap.createBitmap(mColors, mTextureWidth, mTextureHeight, Bitmap.Config.ARGB_8888);
    }

    @Override
    public IBitmapTextureAtlasSource deepCopy() {
        return new BitmapTextureAtlasTextureSource(Bitmap.createBitmap(mColors, mTextureWidth, mTextureHeight, Bitmap.Config.ARGB_8888));
    }

    @Override
    public Bitmap onLoadBitmap(Config pBitmapConfig, boolean pMutable) {
        // TODO Auto-generated method stub
        return null;
    }
}

SpriteTextureRegions创建两个(我想要按钮的 2 个状态:选中/未选中),并将它们附加到HUD

int textureSizeX = 512, textureSizeY = 512;
TextureRegion textureDefault = AndEngineUtils.textureRegionFromDrawable(activity, R.drawable.custom_menu_button, textureSizeX, textureSizeY);
TextureRegion textureSelected = AndEngineUtils.textureRegionFromDrawable(activity, R.drawable.custom_menu_button_selected, textureSizeX, textureSizeY);
mGameHUD = new HUD();

// 2 sprites for selected and unselected
final Sprite buttonUnselected, buttonSelected ;
buttonSelected = new Sprite(0, 0, textureSelected, activity.getVertexBufferObjectManager());
buttonSelected.setVisible(false);

buttonUnselected = new Sprite(0, 0, textureDefault, activity.getVertexBufferObjectManager()) {
    @Override
    public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY) {
        switch (pSceneTouchEvent.getAction()) {
        case TouchEvent.ACTION_DOWN:
            // Change button
            buttonSelected.setVisible(true);
            this.setVisible(false);
            break;
        case TouchEvent.ACTION_UP:
            // reset button
            this.setVisible(true);
            buttonSelected.setVisible(false);
            break;
        default:
            break;
        }
        return super.onAreaTouched(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY);
    }
};
mGameHUD.attachChild(buttonSelected);
mGameHUD.attachChild(buttonUnselected);
mGameHUD.registerTouchArea(buttonUnselected);
camera.setHUD(mGameHUD);

我们还可以利用scene.setOnAreaTouchListener(touchListener)“不需要的”滑动手势(直到按钮之外)来重置按钮颜色(请参阅此线程)。

我刚开始使用AndEngine,还不熟悉最佳实践,请随时纠正我。

于 2013-09-03T07:06:20.283 回答