Android 2D画布游戏 - 绘制背景位图

时间:2017-03-08 15:59:37

标签: android bitmap out-of-memory android-canvas 2d-games

我正在开发一款简单的2D Android游戏,我希望在关卡开始时绘制每个关卡的背景。每个级别的背景都是静态的,它不会动画或移动。

首先,我使用画布在自定义视图中绘制背景,然后我将该视图作为关卡的背景加载。这很有用,但是我注意到如果我绘制了很多线条和形状,UI就开始变得口吃了。我通过画布绘制背景并将其直接保存到位图中解决了问题,然后我将其加载到背景ImageView中,如下所示:

CustomView bgView = new CustomView(this); //this view draws the background
Bitmap bitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
bgView.draw(canvas);
ImageView imageViewBg = (ImageView) findViewById(R.id.imageViewBg);
imageViewBg.setImageBitmap(bitmap);

我注意到这种方法的问题是我正在创建一个大小为[screenWidth x screenHeight]的位图,这可能会导致OutOfMemoryError

那么,绘制全屏游戏背景的最佳方法是什么?问题是我想动态绘制它,我无法直接从资产中加载它。 (我可以使用Bitmap.Config.RGB_565配置文件,但它只会将位图的大小减半,这不是最佳解决方案。)

1 个答案:

答案 0 :(得分:0)

我使用Bitmap.createScaledBitmap()

Bitmap b = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.background),WIDTH,HEIGHT,false);

获取width and height of the screen

然后像往常一样画画:

canvas.drawBitmap(b, 0, 0, null);

修改

以您想要的任何方式加载位图。出于示例的目的,Bitmap对象将被称为b。首先是:

WIDTH = b.getWidth();
HEIGHT = b.getHeight();

继续渲染:

public void render(Canvas c){
    final float scaleFactorX = getWidth()/(WIDTH*1.f);
    final float scaleFactorY = getHeight()/(HEIGHT*1.f);
    //check if the canvas is null first.
    int savedState = c.getSaveCount();
    c.scale(scaleFactorX, scaleFactorY);
    //draw your bitmap.
    c.restoreToCount();
    //Do normal rendering

}

说明

我在这里做的是仅为位图缩放渲染。这意味着任何其他呈现的内容都不会受此影响。

我们需要获取缩放因子以在渲染位图时缩放屏幕:

final float scaleFactorX = getWidth()/(WIDTH*1.f);
final float scaleFactorY = getHeight()/(HEIGHT*1.f);

然后保存画布的状态以便稍后重新加载。

int savedState = c.getSaveCount();

现在我们使用先前定义的scaleFactors

来缩放位图
c.scale(scaleFactorX, scaleFactorY);

并将位图恢复到其原始状态,以便以您需要的任何类型的比例绘制其他所有内容。如果您不需要缩放位图(如果您有缩放),则可以在背景缩放后添加该缩放。

    c.restoreToCount();