几天前我遇到了同样的问题,但我找不到正确的答案。所以现在我已经从不同的来源收集了信息,这就是我处理这个问题的方法。
AFAIK,似乎createFromResource(atlas, getApplicationContext(), R.drawable.drawableId, 0, 0)
from的方法BitmapTextureAtlasTextureRegionFactory
无法处理 XML drawable(例如<shape>...</shape>
)。
事实上,当我只显示一个彩色矩形时,一切都很好 - 我认为也是 PNG 文件 - 但是当我尝试Sprite
从我的 XML 可绘制对象创建一个时,我总是NullBitmapException
在绘图发生时得到一个。
我采取的步骤:
- 将可绘制资源转换为
Drawable
- 转换
Drawable
为Bitmap
(此处来源)
- 转换
Bitmap
为TextureRegion
(这是我使用它的地方)
Sprite
从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
从TextureRegion
s创建两个(我想要按钮的 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
,还不熟悉最佳实践,请随时纠正我。