我正在尝试创建一个AndEngine HUD,它将位于TMXTiledMap的顶部(跟我一起,我对AndEngine很新)。为了简单起见,我有一个通过Android drawables创建的简单矩形。这个想法是,它将位于屏幕的底部中心,并且永远不会移动,即使其下方的地图向各个方向移动也是如此。现在,我想做的就是让那个矩形出现。稍后我会在矩形中添加其他功能。
我的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接受我的实例化。不确定我是否正确这样做。
我在此代码中看到的另一个问题是,在我看来,此代码只是在屏幕上放置一个非活动形状。我知道在我原来的帖子中,我说我的直接目标是让这个矩形显示出来,但我认为它必须显示为一个注册的触摸区域,因为它最终会有一些需要响应的控件用户命令。对不起,如果我过度地减少了我想要做的事情。
我还没有得到这个。有人有什么建议吗?再次感谢!
答案 0 :(得分:2)
您无法将LinearLayout
转换为ITouchArea
,ITouchArea
是仅由AndEngine类实现的接口。
与正宗白布鞋建议一样,你应该使用createFromResource
的{{1}}方法。
您可以使用此代码:
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));
HUD中的触摸区域。
rect
答案 1 :(得分:0)
几天前我遇到了同样的问题,我找不到合适的答案。所以现在我收集了不同来源的信息,这就是我处理这个问题的方法。
AFAIK,来自createFromResource(atlas, getApplicationContext(), R.drawable.drawableId, 0, 0)
的{{1}}方法似乎无法处理XML drawable(例如BitmapTextureAtlasTextureRegionFactory
)。
实际上,当我只显示一个彩色矩形时,一切都很好 - 而且我认为也有一个PNG文件 - 但是当我尝试从我的XML drawable中创建一个<shape>...</shape>
时,我当绘图发生时,总是得到Sprite
。
我采取的步骤:
NullBitmapException
Drawable
转换为Drawable
(Source here)Bitmap
转换为Bitmap
(这是我使用的地方this)TextureRegion
创建Sprite
(或选择/取消选择两个,如here)TextureRegion
附加到游戏的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;
}
}
创建两个Sprite
(我的按钮需要2个状态:已选中/未选中),并将它们附加到TextureRegion
< / p>
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);
来制作一个“不需要的”滑动手势 - 直到按钮外部 - 采取措施重置按钮颜色(参见this thread)。
我刚开始使用scene.setOnAreaTouchListener(touchListener)
并且我还不熟悉最佳做法,所以请随时纠正我。