【问题标题】:Android 2D canvas game - draw background bitmapAndroid 2D画布游戏-绘制背景位图
【发布时间】:2017-03-08 15:59:37
【问题描述】:

我正在开发一个简单的 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 配置文件,但它仍然只会将位图的大小减半,这不是最佳解决方案。

【问题讨论】:

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


    【解决方案1】:

    我用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);
    

    编辑:

    以任何您喜欢的方式加载位图。出于示例的目的,位图对象将被称为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();
    

    【讨论】:

    • 我可以看到您正在从资源中加载位图,而我想从头开始创建它。还有,如果位图有屏幕的大小,在字节分配上是不是还是挺大的?
    • 我从资源中加载它以使其可测试。如何加载位图取决于您。好像内存一样,这是我这里没有考虑的问题。我将用不同的解决方案更新答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 2023-03-07
    • 2014-04-30
    • 2013-04-06
    • 1970-01-01
    相关资源
    最近更新 更多